İ developed a web application using spring and hibernate. This is pretty huge app and i have to get some services from outside of controllers as well. For this i used xmlclasspathcontext to get beans at the same time.
Currently i am using threadlocal and opensession. So far i do not have problem except reading old data when update somethings. İ know this happens because of threadlocal keep current session.
What i want to learn is, İF i remove threadlocal and use öpensession and close session is it a good approach?
Because i cant use getcurrentsession with controllers and getbeans at the same time. İam getting no session found err at the xmXML get bean side. Is there a way to get getcurrentsession at both side? Or do i haveto use open and close session approach? What İF i do not close each opwnsession?
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.yupsoft.grid" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/grid" />
<property name="username" value="myuser" />
<property name="password" value="mypass" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.yupsoft.yupsoft.model.LanguageTextParameter</value>
<value>com.yupsoft.yupsoft.model.LoginHistory</value>
<value>com.yupsoft.yupsoft.model.Session</value>
<value>com.yupsoft.yupsoft.model.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!--
<prop key="hibernate.connection.autocommit">false</prop>
-->
<prop key="hibernate.connection.charSet">utf8</prop>
<prop key="hibernate.connection.characterEncoding">utf8</prop>
<prop key="hibernate.connection.useUnicode">true</prop>
<prop key="hibernate.connection.autoReconnect">true</prop>
<prop key="current_session_context_class">thread</prop>
<prop key="hibernate.connection.pool_size">1</prop>
<prop key="hibernate.c3p0.min_size">10</prop>
<prop key="hibernate.c3p0.max_size">100</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.c3p0.idle_test_period">30</prop>
<prop key="hibernate.c3p0.acquire_increment">1</prop>
<prop key="hibernate.c3p0.max_statements">0</prop>
<prop key="hibernate.c3p0.preferredTestQuery">select 1;</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="hibernate.connection.isolation">8</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
</props>
</property>
</bean>
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
This is Controller class that I am getting requests
#Controller
public class UserController {
#Autowired
private UserService userService;
#Autowired
private LoginHistoryService loginHistoryService;
#RequestMapping(value = "/loginAttempt", method = RequestMethod.POST)
public #ResponseBody
String loginAttempt(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
String password = request.getParameter("password");
User user = userService.getByUserNameAndPassword(userName, password);
if (user != null) {
if (user.isActive()) {
LoginHistory loginHistory = new LoginHistory();
loginHistory.setCreated(new Date());
loginHistory.setIpAddress(request.getRemoteAddr());
loginHistory.setSessionId(request.getSession().getId());
loginHistory.setAccountVerified(Boolean.TRUE);
loginHistory.setUser(user);
boolean loginHistoryCreated = loginHistoryService.create(loginHistory);
if (loginHistoryCreated) {
return "ok";
} else {
//Error
return "err";
}
} else {
return "err";
}
}
return "ok";
}
}
This is Service layer
#Service("loginHistoryService")
#Transactional(propagation = Propagation.REQUIRED, readOnly = true, isolation = Isolation.SERIALIZABLE)
public class LoginHistoryServiceImpl extends GenericServiceImpl implements LoginHistoryService {
#Autowired
private LoginHistoryDAO loginHistoryDAO;
public LoginHistoryDAO getLoginHistoryDAO() {
return loginHistoryDAO;
}
public void setLoginHistoryDAO(LoginHistoryDAO loginHistoryDAO) {
this.loginHistoryDAO = loginHistoryDAO;
setGenericDAO(loginHistoryDAO);
}
#Transactional(propagation = Propagation.REQUIRED, readOnly = false)
#Override
public boolean create(LoginHistory obj) {
return loginHistoryDAO.create(obj);
}
This part is DAO layer
#Repository("loginHistoryDAO")
public class LoginHistoryDAOImpl extends GenericDAOImpl implements LoginHistoryDAO {
#Autowired
private SessionDAO sessionDAO;
#Override
public boolean create(LoginHistory obj) {
try {
//beginTransaction();
save(obj);
if (obj.isAccountVerified()) {
Session s = new Session();
s.setActive(Boolean.TRUE);
s.setIpAddress(obj.getIpAddress());
s.setCreated(new Date());
s.setSessionId(obj.getSessionId());
s.setUser(obj.getUser());
sessionDAO.save(s);
}
//commitTransaction();
} catch (Exception e) {
handleException(e);
return false;
}
return true;
}
}
And last part is generic part
#SuppressWarnings("unchecked")
#Repository
public abstract class GenericDAOImpl implements GenericDAO {
#Autowired
private SessionFactory sessionFactory;
private final Class<T> persistentClass;
public GenericDAOImpl() {
this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
public Class<T> getPersistentClass() {
return persistentClass;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session getCurrentSession() throws HibernateException {
return sessionFactory.getCurrentSession();
}
#Override
public Transaction beginTransaction() {
return getCurrentSession().beginTransaction();
}
#Override
public void commitTransaction() {
getCurrentSession().getTransaction().commit();
I am trying to replace openSession() to getCurrentSession()
and I require to control beginTransaction() and tx.commit(). Because I have more than one entity to save or update at the same time. So, I need to wrap those intities in a transaction, be sure all done or all did not done.
When I use getCurrentSession() I am getting this error;
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:656)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:560)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.virdyn.grid.core.system.filter.SessionFilter.doFilter(SessionFilter.java:88)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.transaction.TransactionSystemException: Could not commit Hibernate transaction; nested exception is org.hibernate.TransactionException: Transaction not successfully started
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:660)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:412)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy166.create(Unknown Source)
at com.virdyn.grid.controller.UserController.loginAttempt(UserController.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:421)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:409)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:771)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
... 25 more
Caused by: org.hibernate.TransactionException: Transaction not successfully started
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
... 43 more
I want to cancel ThreadLocal and use getCurrentSession.
What is wrong in here Or do you have other purposes. In fact I can use opensession() and closeSession for any method in all dao's. If I do that is it to slow my system?
I am waiting solutions thanks
Related
I'm trying to get Javer setup with my project. I am using Hibernate JPA and I believe I have everything configured correctly.
Here is my Spring config:
<bean id="auditDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.audit.url}"/>
<property name="username" value="${jdbc.audit.username}"/>
<property name="password" value="${jdbc.audit.password}"/>
<property name="maxActive" value="100"/>
<property name="maxWait" value="1000"/>
<property name="poolPreparedStatements" value="true"/>
<property name="defaultAutoCommit" value="true"/>
<property name="validationQuery" value="${jdbc.validationQuery}"/>
<property name="testOnBorrow" value="true"/>
</bean>
<bean id="auditSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" destroy-method="destroy">
<property name="dataSource" ref="auditDataSource"/>
<property name="configLocation" value="classpath:hibernate.audit.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.use_sql_comments">false</prop>
<!--<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>-->
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<!-- Hibernate Search index directory -->
<prop key="hibernate.search.default.indexBase">${app.search.index.basedir}</prop>
</props>
<!-- Turn batching off for better error messages under PostgreSQL -->
<!-- hibernate.jdbc.batch_size=0 -->
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="auditTransactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="auditSessionFactory"/>
</bean>
<bean id="javersRepoConnectionProvider" class="com.dsc.discus.ng.audit.javers.JaversRepoConnectionProvider">
<constructor-arg name="dataSource" ref="auditDataSource"/>
</bean>
<bean id="auditController" class="com.dsc.discus.ng.audit.javers.JaversAuditController">
<constructor-arg name="javersRepoConnectionProvider" ref="javersRepoConnectionProvider"/>
<constructor-arg name="transactionManager" ref="auditTransactionManager"/>
</bean>
The JaversAuditController bean:
public class JaversAuditController extends AuditController {
private final JaversSqlRepository javersSqlRepository;
private final Javers javers;
public JaversAuditController(JaversRepoConnectionProvider javersRepoConnectionProvider, PlatformTransactionManager transactionManager) {
javersSqlRepository = SqlRepositoryBuilder.sqlRepository()
.withConnectionProvider(javersRepoConnectionProvider)
.withDialect(DialectName.MYSQL)
.build();
javers = TransactionalJaversBuilder.javers()
.withTxManager(transactionManager)
.withObjectAccessHook(new HibernateUnproxyObjectAccessHook())
.withMappingStyle(MappingStyle.BEAN)
.registerJaversRepository(javersSqlRepository)
.build();
}
#Override
public void addModified(BaseEntity entity) {
addModified(entity, null);
}
#Override
public void addModified(BaseEntity entity, Map<String, String> extraParams) {
if (javers != null && entity != null) {
if (extraParams != null) {
javers.commit(entity.getModifiedBy(), entity, extraParams);
}
else {
javers.commit(entity.getModifiedBy(), entity);
}
}
}
public JaversSqlRepository getJaversSqlRepository() {
return javersSqlRepository;
}
public Javers getJavers() {
return javers;
}
I have to use BEAN mapping style because the JPA annotations are on the accessors of the entities.
Here is the JaversRepoConnectionProvider bean:
public class JaversRepoConnectionProvider implements ConnectionProvider {
private DataSource dataSource;
public JaversRepoConnectionProvider(DataSource dataSource) {
this.dataSource = dataSource;
}
#Override
public Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
I am doing a manual audit. That is, every time an entity is saved, I'm calling the javers.commit() method. As it happens, the very first thing I try to save causes a MySQL syntax error stating that the table "jv_commit" doesn't exist. The documentation states that the necessary tables would automatically be created, so I must be missing something. Please advise and thanks in advance.
Truncated stack trace:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'discus_eng_audit.jv_commit' doesn't exist
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)
at com.mysql.jdbc.Util.getInstance(Util.java:386)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4237)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4169)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2617)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2778)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2825)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2156)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:2323)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:96)
at org.polyjdbc.core.transaction.Transaction.executeQuery(Transaction.java:59)
at org.polyjdbc.core.query.TransactionalQueryRunner.queryCollection(TransactionalQueryRunner.java:86)
at org.polyjdbc.core.query.TransactionalQueryRunner.queryList(TransactionalQueryRunner.java:76)
at org.javers.repository.sql.PolyUtil.queryForBigDecimalList(PolyUtil.java:27)
at org.javers.repository.sql.PolyUtil.queryForOptionalBigDecimal(PolyUtil.java:36)
at org.javers.repository.sql.repositories.CommitMetadataRepository.selectMaxCommitId(CommitMetadataRepository.java:86)
at org.javers.repository.sql.repositories.CommitMetadataRepository.getCommitHeadId(CommitMetadataRepository.java:75)
at org.javers.repository.sql.JaversSqlRepository.getHeadId(JaversSqlRepository.java:76)
at org.javers.repository.api.JaversExtendedRepository.getHeadId(JaversExtendedRepository.java:137)
at org.javers.core.commit.CommitIdFactory.nextId(CommitIdFactory.java:26)
at org.javers.core.commit.CommitFactory.newCommitMetadata(CommitFactory.java:79)
at org.javers.core.commit.CommitFactory.create(CommitFactory.java:69)
at org.javers.core.JaversCore.commit(JaversCore.java:82)
at org.javers.core.JaversCore.commit(JaversCore.java:67)
at org.javers.spring.jpa.JaversTransactionalDecorator.commit(JaversTransactionalDecorator.java:58)
at com.dsc.discus.ng.audit.javers.JaversAuditController.addModified(JaversAuditController.java:56)
at com.dsc.discus.ng.audit.javers.JaversAuditController.addModified(JaversAuditController.java:46)
at com.dsc.discus.ng.model.persistence.dao.hibernate.BaseDaoHibernate.save(BaseDaoHibernate.java:146)
at com.dsc.discus.ng.model.persistence.dao.hibernate.BaseDaoHibernate.save(BaseDaoHibernate.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
In Spring app, Javers instance should be registered as a Spring bean. JaVers uses #PostConstruct annotation and Spring calls ensureSchema() when txManager is ready.
See JaversTransactionalDecorator impl:
#PostConstruct
public void ensureSchema() {
TransactionTemplate tmpl = new TransactionTemplate(txManager);
tmpl.execute(new TransactionCallbackWithoutResult() {
#Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
javersSqlRepository.ensureSchema();
}
});
}
In your case, this method isn't called because you have created the Javers instance in your Controller and not as a Spring bean. You should configure your app as docs says - https://javers.org/documentation/spring-integration/#jpa-entity-manager-integration
It turns out that the TransactionalJaversBuilder.javers().build() method does not ensure the tables are created, like the standard JaversBuilder.javers().build() method does. I am not sure if this is bug in the TransactionalJaversBuilder or not. My workaround is to call the ensureSchema() after the Javers object is built:
public JaversAuditController(JaversRepoConnectionProvider javersRepoConnectionProvider, PlatformTransactionManager transactionManager) {
javersSqlRepository = SqlRepositoryBuilder.sqlRepository()
.withConnectionProvider(javersRepoConnectionProvider)
.withDialect(DialectName.MYSQL)
.build();
javers = TransactionalJaversBuilder.javers()
.withTxManager(transactionManager)
.withObjectAccessHook(new HibernateUnproxyObjectAccessHook())
.withMappingStyle(MappingStyle.BEAN)
.registerJaversRepository(javersSqlRepository)
.build();
javersSqlRepository.ensureSchema();
}
I am having difficulties while trying to launch my application, I am stuck somewhere in the code.
my entity class is:
#Entity
#Table(name="metalocation")
public class Location implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="ID")
private int id;
#Column(name="DB_ID")
private String dbId;
#Column(name="GEO_LAT")
private double geoLAT;
#Column(name="GEO_LNG")
private double geoLNG;
#Column(name="IN_LOCATION")
private int inLocation;
#Column(name="ISO")
private String iso;
#Column(name="LOCAL_NAME")
private String localName;
#Column(name="TYPE")
private char type;
#OneToMany(cascade=CascadeType.PERSIST)
#JoinColumn(name="meta_address_fk")
private Set<Address> address;
public Location() {
}
.......... All setters and getters
my Service interface is:
import java.util.List;
import com.platformhouse.clinicsystem.web.model.entity.Address;
import com.platformhouse.clinicsystem.web.model.entity.Location;
public interface AddressService {
public List<Location> getAllCountries();
}
my service class is:
#Service("adressService")
#Transactional
public class AddressServiceImplementation implements AddressService {
private AddressDAO addressDAO;
//
public void setPatientDao(AddressDAO addressDAO) {
this.addressDAO = addressDAO;
}
#Transactional
public List<Location> getAllCountries() {
return this.addressDAO.getAllCountries();
}
}
My DAO is:
#Repository
#Transactional
public class AddressDAO {
#Autowired
private SessionFactory session;
public void setSession(SessionFactory session) {
this.session = session;
}
public Session session(){
return session.getCurrentSession();
}
#SuppressWarnings("unchecked")
public List<Location> getAllCountries() {
Query query = session().createQuery("from Location where inLocation <=246");
List<Location> results = query.list();
return results;
}
}
my Controller is:
#Controller
#RequestMapping(value = "/usersignup")
public class PatientSignupController {
private PatientService patientService;
private AddressService addressService;
#RequestMapping(value = "/usersignup")
public String signup() {
return "usersignup";
}
#RequestMapping( method = RequestMethod.GET)
public List<Location> getCountries() {
return this.addressService.getAllCountries();
}
}
my hibernate xml:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<context:component-scan base-package="com.platformhouse.clinicsystem.web.dao">
</context:component-scan>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.platformhouse.clinicsystem.web.model.entity.User</value>
<value>com.platformhouse.clinicsystem.web.model.entity.UserType</value>
</value>
<value>com.platformhouse.clinicsystem.web.model.entity.Location
</value>
<
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="javax.persistence.validation.group.pre-persist">com.platformhouse.clinicsystem.web.validation.PersistenceValidationGroup
</prop>
<prop key="javax.persistence.validation.group.pre-update">com.platformhouse.clinicsystem.web.validation.PersistenceValidationGroup
</prop>
<prop key="javax.persistence.validation.group.pre-remove">com.platformhouse.clinicsystem.web.validation.PersistenceValidationGroup
</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.platformhouse.clinicsystem.web.dao</value>
<value>com.platformhouse.clinicsystem.web.service.implementation</value>
</list>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="exceptionTranslator"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</bean>
my JSp code is:
<form method="Get">
<label>Country/region:</label>
<select id="iCountry" name="iCountry">
<c:forEach items="${locationList}" var="country">
<option selected="selected" value="">please select country</option>
<option value="${country.id}">${country.localName}</option>
</c:forEach>
<select />
my results are:
HTTP Status 500 - Request processing failed; nested exception is java.lang.NullPointerException
**type Exception report
message Request processing failed; nested exception is java.lang.NullPointerException
description The server encountered an internal error that prevented it from fulfilling this request.
exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
root cause
java.lang.NullPointerException
----------
// controller error
com.platformhouse.clinicsystem.web.controller.PatientSignupController.getCountries(PatientSignupController.java:40)
----------
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:777)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:706)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
You have forgot to add #Autowired annotation for your services. Thats why you are getting NullPointerException. Please check below
#Autowired
private PatientService patientService;
#Autowired
private AddressService addressService;
Update
You have mentioned it as #Service("adressService"). addressService is not spelled correctly.
change it to #Service("addressService")
I've read tens of topics and no result.
What the problem:
I can't get current hibernate session in #Transactional method.
EXCEPTION:
Exception in thread "main" org.hibernate.HibernateException: No Session found for current thread
at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:988)
at name.krestjaninoff.activiti.hello.core.Engine.getHibernateSession(Engine.java:27)
at name.krestjaninoff.activiti.hello.process.CreateClientService.execute(CreateClientService.java:42)
at org.activiti.engine.impl.bpmn.JavaDelegateDelegate.execute(JavaDelegateDelegate.java:48)
at org.activiti.engine.impl.bpmn.JavaDelegateDelegate.execute(JavaDelegateDelegate.java:39)
at org.activiti.engine.impl.bpmn.ClassDelegate.execute(ClassDelegate.java:96)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:40)
....
My Code:
#Service
#EnableTransactionManagement(proxyTargetClass=true, mode= AdviceMode.PROXY)
public class CreateClientService {
#Transactional(value="transactionManager", propagation = Propagation.REQUIRED)
public void execute() {
((SessionFactory) applicationContext.getBean("sessionFactory")).getCurrentSession(); //EXCEPTOIN!!!
}
}
My configurations:
<tx:annotation-driven/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" scope="singleton">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>name.krestjaninoff.activiti.hello.db</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
<!--<prop key="hibernate.hbm2ddl.auto">create</prop>-->
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" scope="singleton">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
<property name="dataSource">
<ref local="dataSource" />
</property>
</bean>
ADDTION: NativeConstructorAccessorImpl class create CreateClientService instance:
#CallerSensitive
public T newInstance(Object ... initargs)
throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException
{
if (!override) {
if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
checkAccess(caller, clazz, null, modifiers);
}
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
ConstructorAccessor ca = constructorAccessor; // read volatile
if (ca == null) {
ca = acquireConstructorAccessor();
}
return (T) ca.newInstance(initargs);
}ected JavaDelegate javaDelegate;
protected JavaDelegateDelegate() {
}
public JavaDelegateDelegate(JavaDelegate javaDelegate) {
this.javaDelegate = javaDelegate;
}
public void execute(ActivityExecution execution) throws Exception {
execute((DelegateExecution) execution);
performDefaultOutgoingBehavior(execution);
}
public void notify(ExecutionListenerExecution execution) throws Exception {
execute((DelegateExecution) execution);
}
public void execute(DelegateExecution execution) throws Exception {
javaDelegate.execute(execution);
}
}
I'm writing a desktop java application for an environment without a network connection. I'm trying to store the application data as securely as I can in an encrypted in-process hsqldb, with an unencrypted user information hsqldb. Hsqldb requires that the crypto_key be set in the jdbcurl when the connection is created. My application uses hibernate to do persistence and Spring to do configuration and injection.
My current scheme is to store username, password hash, salt and the encrypted database's crypto_key in the unencrypted user table. The crypto_key is protected by an asymmetric encryption using the user's password as the key. Thus, the application doesn't know what the crypto_key for the application data is until after it has been running long enough to load a gui, and authenticate the user.
Here is my current applicationContext.xml. Spring uses it to get Hibernate going and functioning.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:component-scan base-package="com.company.domain" />
<context:component-scan base-package="com.company.service" />
<tx:annotation-driven />
<bean id="userDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:./ReviewDatabase/users" />
<property name="username" value="reviewer" />
<property name="password" value="$kelatonKey" />
</bean>
<bean id="mainDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url"
value="jdbc:hsqldb:./ReviewDatabase/data" /> <!-- TODO: ;crypt_key=;crypt_type=AES -->
<property name="username" value="reviewer" />
<property name="password" value="$kelatonKey" />
</bean>
<bean id="userSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="userDataSource" />
<property name="annotatedClasses">
<list>
<value>com.company.domain.AppUser</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="mainSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="mainDataSource" />
<property name="annotatedClasses">
<list>
<!-- <value>com.companu.domain.Person</value> -->
<!-- <value>com.company.domain.Thing</value> -->
<!-- <value>com.company.domain.Thing1</value> -->
<!-- <value>com.company.domain.Thing2</value> -->
<!-- <value>com.company.domain.Review</value> -->
</list>
</property>
<property name="hibernateProperties">
<props>
<pro key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="mainTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mainSessionFactory" />
</bean>
<bean id="userTransactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="userSessionFactory" />
</bean>
</beans>
Here's an example of a class where I would like to have the SessionFactory injected
#Repository("ReviewDao")
public class HibernateReviewDao implements ReviewDao{
private SessionFactory mainSessionFactory;
#Autowired
public void setMainSessionFactory(
SessionFactory mainSessionFactory){
this.mainSessionFactory = mainSessionFactory;
}
#Override
#Transactional(value = "mainTransactionManager")
public void store(Review review) {
mainSessionFactory.getCurrentSession().saveOrUpdate(review);
}
#Override
#Transactional(value = "mainTransactionManager")
public void delete(Long reviewId) {
Review review = (Review)mainSessionFactory.getCurrentSession()
.get(Review.class, reviewId);
mainSessionFactory.getCurrentSession().delete(review);
}
}
And finally, here's what I've tried to do after authenticating the user and getting that crypto_key.
String jdbcUrl = "jdbc:hsqldb:./ReviewDatabase/data2;crypt_key=" + secret + ";crypt_type=AES";
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySetting("hibernate.dialect", "org.hibernate.dialect.HSQLDialect")
.applySetting("hibernate.show_sql", "true")
.applySetting("hibernate.hbm2ddl.auto","update")
.applySetting("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver")
.applySetting("hibernate.connection.url", jdbcUrl)
.applySetting("hibernate.connection.username", "reviewer")
.applySetting("hibernate.connection.password", "$kelatonKey")
.buildServiceRegistry();
SessionFactory mainSessionFactory = new MetadataSources(serviceRegistry)
.addAnnotatedClass(com.company.domain.Review.class)
.addAnnotatedClass(com.company.domain.Person.class)
.addAnnotatedClass(com.company.domain.Thing.class)
.addAnnotatedClass(com.company.domain.Thing1.class)
.addAnnotatedClass(com.company.domain.Thing2.class)
.buildMetadata()
.buildSessionFactory();
org.springframework.orm.hibernate4.HibernateTransactionManager htm =
(HibernateTransactionManager)context.getBean("mainTransactionManager");
context.getAutowireCapableBeanFactory().initializeBean(mainSessionFactory, "mainSessionFactory");
htm.setSessionFactory(mainSessionFactory);
However, with that, the first query to the object above results in org.hibernate.HibernateException: No Session found for current thread
How can I change the jdbcurl long after hibernate has initialized, dependencies have been injected and other various kinds of tom-foolery has occurred?
I've been putting this part of development off, hoping Google would eventually come through, but I'm out of ideas to search for. All answers will be accepted with sheepish humility :)
I wonder if this might help, Can I replace a Spring bean definition at runtime? , you could dummy up the bean properties to start with and then change the bean in runtime.
So, the missing bit of the recipe was LocalSessionFactoryBean. It got the sessionFactory setup so I could just replace the sessionFactories that are created at initialization.
Here's the code I had to change from the question
org.springframework.orm.hibernate4.HibernateTransactionManager htm =
(HibernateTransactionManager)context.getBean("mainTransactionManager");
Class<?>[] classes = new Class<?>[5];
classes[0] = com.company.domain.Thing1.class;
classes[1] = com.company.domain.Thing2.class;
classes[2] = com.company.domain.Person.class;
classes[3] = com.company.domain.Thing.class;
classes[4] = com.company.domain.Review.class;
String jdbcUrl = "jdbc:hsqldb:./ReviewDatabase/data3;crypt_key=" + secret + ";crypt_type=AES";
java.util.Properties hibernateProperties = new java.util.Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto","update");
hibernateProperties.setProperty("hibernate.connection.driver_class", "org.hsqldb.jdbcDriver");
hibernateProperties.setProperty("hibernate.connection.url", jdbcUrl);
hibernateProperties.setProperty("hibernate.connection.username", "reviewer");
hibernateProperties.setProperty("hibernate.connection.password", "$kelatonKey");
LocalSessionFactoryBean slfb = new LocalSessionFactoryBean();
slfb.setHibernateProperties(hibernateProperties);
slfb.setAnnotatedClasses(classes);
try {
slfb.afterPropertiesSet();
} catch (IOException e) {
Log.warn("Cannot connection to application database");
Log.write(e.getLocalizedMessage());
Log.write(e.getStackTrace());
return;
}
SessionFactory mainSessionFactory = slfb.getObject();
context.getAutowireCapableBeanFactory().initializeBean(mainSessionFactory, "mainSessionFactory");
htm.setSessionFactory(mainSessionFactory);
for(ListenForNewSessionFactory dao : daos){
dao.setNewSessionFactory(mainSessionFactory);
}
I had each Dao implement an interface to set the sessionFactory, and had each of them add themselves to a static list on initialization. It's not very reusable, but it works.
I used the following hack - wherever I needed a SessionFactory, I used a SessionFactoryFactory (below) instead - delegates the only SessionFactory method I actually use.
#Component
public class SessionFactoryFactory {
#Autowired
private LocalSessionFactoryBean sessionFactoryBean;
#Autowired
private DriverManagerDataSource dataSource;
private SessionFactory sessionFactory;
private SessionFactory getSessionFactory() {
if (null == sessionFactory) {
sessionFactory = sessionFactoryBean.getObject();
}
return sessionFactory;
}
public Session openSession() {
return getSessionFactory().openSession();
}
public void updateDataSourceUrl() throws IOException {
sessionFactory = null;
sessionFactoryBean.afterPropertiesSet();
}
}
I've seen several similar questions, but none of the suggested solutions helped me.
Summary: when I create and inject the beans on the .xml, it works; but when I use #Autowire or #Resource, it doesn't.
Environment: Spring3, Hibernate4, Tomcat7.
Details: the following setup DOES work:
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring/root-context.xml
/WEB-INF/spring/security-context.xml
/WEB-INF/spring/users-context.xml
</param-value>
</context-param>
root-context.xml:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/venus" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.airbus.genesis.marte.dal" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
users-context.xml:
<bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
BL object:
#Service("usersManager")
#Transactional(readOnly = true)
public class UsersManager implements IUsersManager {
#Autowired
#Qualifier("usersDAO")
private IUsersDAO usersDAO;
#Override
public List<User> getUsers() {
return usersDAO.getUsers();
}
}
DAO object (notice that #Repository and #Resource are commented):
//#Repository("usersDAO")
#Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {
// #Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
#Override
public List<User> getUsers() {
#SuppressWarnings("unchecked")
List<User> res = (List<User>) getSessionFactory().getCurrentSession()
.createQuery("from User").list();
return res;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
But the following one DOES NOT work:
users-context.xml:
<!--
<bean id="usersDAO" class="com.airbus.genesis.marte.dal.users.UsersDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
-->
DAO object (notice that #Repository and #Resource are uncommented now):
#Repository("usersDAO")
#Transactional(readOnly = true)
public class UsersDAO implements IUsersDAO {
#Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
#Override
public List<User> getUsers() {
#SuppressWarnings("unchecked")
List<User> res = (List<User>) getSessionFactory().getCurrentSession()
.createQuery("from User").list();
return res;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
}
org.hibernate.HibernateException: No Session found for current thread is raised:
org.hibernate.HibernateException: No Session found for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
com.airbus.genesis.marte.dal.users.UsersDAO.getUsers(UsersDAO.java:23)
com.airbus.genesis.marte.bl.users.UsersManager.getUsers(UsersManager.java:22)
[...]
The same happens if I use #Autowire instead of #Resource.
I guess it is some kind of misunderstanding on my side, but cannot find where. Any idea?
The problem is likely that #Repository and #Service annotations are being picked up in the dispatcher-servlet.xml configuration (do you use context:component-scan?), so these beans are created in the dispatcher servlet context instead of the root web app context.
A good practice is to put your service layer objects to the dedicated packages and use the specific package name as <context:component-scan/> base-package qualifier (like 'com.myproject.services'). You can also use filter expressions to include and exclude elements see examples here : #Service are constructed twice
and 4.10.3 section of the Spring documentation
See also Difference between applicationContext.xml and spring-servlet.xml in Spring Framework