I am running spring 4.1.4, hibernate 4.3.8, atomikos 3.9.3, java 8, tomcat 8.
I see the above exception in localhost.log when I start my server but I'm not sure where to configure the TransactionManagerLookup apart from where I am already configuring it. This wasn't happening before upgrading hibernate so it is most likely a versioning issue. Could anyone help please?
FYI: catalina.out shows nothing useful. Just:
SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Error listenerStart
SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.startInternal Context [] startup failed due to previous errors
My appContext defines :
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
and the full stack trace is:
22-Jan-2015 10:07:25.734 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class com.my.app.web.InitializerListener
org.hibernate.HibernateException: No TransactionManagerLookup specified
at org.hibernate.context.internal.JTASessionContext.currentSession(JTASessionContext.java:85)
at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1014)
at com.my.app.dao.AbstractMyDAO.currentSession(AbstractMyDAO.java:116)
at com.my.app.dao.AbstractMyDAO.criteria(AbstractMyDAO.java:86)
at com.my.app.dao.AbstractMyDAO.count(AbstractMyDAO.java:79)
at com.my.app.initialize.MyInitializerImpl.initializeApplicaiton(MyInitializerImpl.java:69)
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:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
at com.sun.proxy.$Proxy220.initializeApplicaiton(Unknown Source)
at com.my.app.web.MyInitializerListener.contextInitialized(MyInitializerListener.java:42)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4772)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5196)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:917)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1701)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
EDIT: The Atomikos Transaction manager is configured as such
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close">
<property name="forceShutdown" value="true" />
<!-- in secs -->
<property name="transactionTimeout" value="300"/>
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<!-- in secs -->
<property name="transactionTimeout" value="300" />
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
<property name="transactionSynchronizationName" value="SYNCHRONIZATION_ON_ACTUAL_TRANSACTION" />
<property name="allowCustomIsolationLevels" value="true"/>
</bean>
EDIT 2:
I think I need to clarify things a bit here.
I have a DAO object called AbstractMyDAO (as you can see from the stack). In this object is defined a session factory
#Autowired
private SessionFactory mySessionFactory;
when currentSession is called the above error is thrown because hibernate cannot find the transaction manager lookup associated with this session factory.
public Session currentSession() {
return mySessionFactory.getCurrentSession();
}
This session factory is defined in my app context file as such:
<bean id="mySessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource">
<ref bean="myDataSource" />
</property>
<property name="annotatedClasses">
<list>
<value>some values... </value>
...
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${gst.hibernate.dialect}
</prop>
<prop key="query.factory_class">
org.hibernate.hql.ast.ASTQueryTranslatorFactory
</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.show_sql">${my.hibernate.showsql}</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_structured_entries">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">${ehcache.my.persist.config}</prop>
<prop key="hibernate.connection.isolation">3</prop>
<prop key="connection.release_mode">auto</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
<prop key="hibernate.search.default.directory_provider">filesystem</prop>
<prop key="hibernate.search.default.indexBase">/var/log/my/lucene/indexes</prop>
</props>
</property>
</bean>
As you can see, the property hibernate.transaction.manager_lookup_class is being defined but can't be found when the bean is created and I have no idea why. Has the configuration changed?
EDIT 3:
When I debug:
final JtaPlatform jtaPlatform = factory().getServiceRegistry().getService( JtaPlatform.class );
It returns a NoJTAPlatform. I guess this is my problem.
EDIT 4:
There doesn't seem to be anything that implements JtaPlatform that is suitable for tomcat or am I being mental?
Make sure you also configure the Atomikos Transaction Manager too, so the TransactionManagerLookup can locate the UserTransaction accordingly:
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager"
init-method="init" destroy-method="close">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp">
<property name="transactionTimeout" value="300" />
</bean>
<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManager" ref="atomikosTransactionManager" />
<property name="userTransaction" ref="atomikosUserTransaction" />
</bean>
Then, you should use Spring EntityManager factory too:
<bean id="entityManager"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource"
p:persistenceXmlLocation="**/persistence.xml"
p:persistenceUnitName="persistenceUnit"
depends-on="dataSource, transactionManager">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
</bean>
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.transaction.factory_class">org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory</prop>
<prop key="hibernate.transaction.manager_lookup_class">com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup</prop>
...
</props>
</property>
</bean>
Then the DAOs should inject the EntityManager:
#PersistenceContext(unitName = "persistenceUnit")
private EntityManager entityManager;
Instead of calling currentSession(AbstractMyDAO) directly:
at com.my.app.dao.AbstractMyDAO.currentSession(AbstractMyDAO.java:116)
The answer to my question is here.
"In Hibernate 4.3 the long deprecated TransactionManagerLookup got removed. Now the JTA provider must implement org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform."
I Solved it by
into the hibernate.cfg.xml file
changing the
<property name="hibernate.current_session_context_class">thread</property>
to thread instead of jta .
More details here
Related
I am migrating an application from
Spring 3.0.5 + JPA 2.0
to
Spring 4 + JPA (Hibernate 4)
I have followed the migration guide : https://github.com/spring-projects/spring-framework/wiki/Migrating-from-earlier-versions-of-the-spring-framework.
The application is using a JTA transaction manager : a Jencks / GeronimoPlatformTransactionManager (because of transactions distributed on datasources and ESB).
The Spring / JPA configuration is :
<bean id="rduEntityManagerFactory" class="ch.vd.dsas.rdu.repository.crud.service.ExtendedLocalContainerEntityManagerFactoryBean"
depends-on="rduTransactionManagerLocator,jGroupsCacheManagerPeerProviderFactoryLocator">
<property name="persistenceUnitName" value="rduPersistenceUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${rdu.jpa.database}" />
</bean>
</property>
<property name="persistenceUnitPostProcessors">
<bean class="ch.vd.dsas.rdu.commons.tx.spring.JtaPersistenceUnitPostProcessor">
<property name="jtaDataSource" ref="rduDataSource" />
</bean>
</property>
<property name="jpaProperties" ref="jpaProperties"/>
</bean>
<util:properties id="jpaProperties">
<prop key="javax.persistence.transactionType">JTA</prop>
<prop key="javax.persistence.validation.mode">CALLBACK</prop>
<prop key="hibernate.hbm2ddl.auto">${rdu.jpa.hbm2ddl.auto}</prop>
<prop key="hibernate.current_session_context_class">jta</prop>
<!-- Transaction properties -->
<prop key="hibernate.transaction.jta.platform">ch.vd.dsas.rdu.ref.transaction.jencks.JencksTransactionManagerLookup</prop>
<prop key="hibernate.transaction.manager_lookup_class">ch.vd.dsas.rdu.transaction.jencks.JencksTransactionManagerLookup</prop>
<prop key="hibernate.default_schema">${rdu.datasource.schemaMetier}</prop>
<!-- Debug properties -->
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
<!-- Cache properties -->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.ReplicatedSingletonEhCacheRegionFactory</prop>
<prop key="hibernate.cache.cluster_name">${rdu.hibernate.cache.jgroups.cluster.name}</prop>
<prop key="net.sf.ehcache.configurationResourceName">/hibernate-ehcache.xml</prop>
</util:properties>
Transactions are annotation driven :
<tx:annotation-driven transaction-manager="rduJtaTransactionManager" />
The transaction manager is declared like that :
<!-- From Jencks org.jencks:jencks:2.2 -->
<bean id="rduJencksTransactionManager" class="org.jencks.factory.TransactionManagerFactoryBean" />
<bean id="rduJtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<qualifier value="rdu" />
<property name="transactionManager" ref="rduJencksTransactionManager" />
<property name="userTransaction" ref="rduJencksTransactionManager" />
</bean>
<bean id="rduTransactionManagerLocator" class="ch.vd.dsas.rdu.transaction.jencks.TransactionManagerLocator" factory-method="getInstance">
<property name="transactionManager" ref="rduJencksTransactionManager"/>
</bean>
The application is starting and accessing data and displaying it.
However no insert / update are performed.
If I change data and submit the change the application receives the change but the data does not get flushed to the database.
I have activated logs and I see the transaction :
rdu 2015-06-18 20:28:01,817 [ http-8080-1] DEBUG [ o.s.t.j.JtaTransactionManager] Creating new transaction with name [org.springframework.data.jpa.repository.support.SimpleJpaRepository.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; 'rdu'
rdu 2015-06-18 20:28:01,817 [ http-8080-1] DEBUG [ o.s.t.j.JtaTransactionManager] Participating in existing transaction
rdu 2015-06-18 20:28:01,823 [ http-8080-1] DEBUG [ o.s.t.j.JtaTransactionManager] Initiating transaction commit
But nothing is sent to the database.
If I intercept the execution through debugging and manually flush the Hibernate session, the data gets updated.
It seems the JPA / Hibernate session is not coordinated with the transaction.
I can't figure out what is missing in the configuration and why the session is not flushed automatically.
Hope you can help me with this issue.
Best regards,
Eric
The problem is due to this property:
<prop key="hibernate.transaction.jta.platform">ch.vd.dsas.rdu.ref.transaction.jencks.JencksTransactionManagerLookup</prop>
The hibernate.transaction.jta.platform property is not the same with hibernate.transaction.manager_lookup_class and it should point to an AbstractJtaPlatform implementation:
<property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.SunOneJtaPlatform"/>
I already created required qurtz table on database and mapped all bean reference of quartz xml correctly but still get exception.
my quartzconfig.xml contains:-
<bean name="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory">
<bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
</property>
<property name="dataSource" ref="dataSource" />
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.misfireThreshold">6000000</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
</prop>
<prop key="org.quartz.jobStore.tablePrefix">qrtz_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
<!-- <prop key="org.quartz.scheduler.instanceName">Scheduler</prop> -->
<prop key="org.quartz.scheduler.instanceName">SgsClusteredScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.scheduler.jmx.export">true</prop>
</props>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="waitForJobsToCompleteOnShutdown" value="true" />
<property name="overwriteExistingJobs" value="true" />
<property name="triggers">
<list>
<ref bean="companySaleUploaderJobTrigger" />
</list>
</property>
</bean>
exception
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'scheduler' defined in ServletContext resource
[/WEB-INF/config/quartzConfig.xml]: Invocation of init method failed;
nested exception is org.quartz.JobPersistenceException: Couldn't store
trigger:
org.springframework.web.context.support.XmlWebApplicationContext [See
nested exception: java.io.NotSerializableException:
org.springframework.web.context.support.XmlWebApplicationContext] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1455)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:591)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469)
at
org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:111)
at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
at
org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
at
org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
at
org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
at
org.apache.catalina.core.StandardService.start(StandardService.java:525)
at
org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
at org.apache.catalina.startup.Catalina.start(Catalina.java:595) at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at
java.lang.reflect.Method.invoke(Unknown Source) at
org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at
org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) Caused
by: org.quartz.JobPersistenceException: Couldn't store trigger:
org.springframework.web.context.support.XmlWebApplicationContext [See
nested exception: java.io.NotSerializableException:
org.springframework.web.context.support.XmlWebApplicationContext]
Error occurs due to confliction of jars . now my problem is solve using two jar.
When i use spring-3.1.2 release jar with quartz-all-1.8.6.jar then my code work fine and now quartz trigger firing with oracle database.
Quartzconfig.xml
<bean name="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory">
<bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
</property>
<property name="dataSource" ref="dataSource" />
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.jobStore.misfireThreshold">6000000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
</prop>
<prop key="org.quartz.jobStore.tablePrefix">qrtz_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">20000</prop>
<!-- <prop key="org.quartz.scheduler.instanceName">Scheduler</prop> -->
<prop key="org.quartz.scheduler.instanceName">SgsClusteredScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.scheduler.jmx.export">true</prop>
<prop key="org.quartz.scheduler.skipUpdateCheck">true </prop>
</props>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext" />
<property name="waitForJobsToCompleteOnShutdown" value="true" />
<property name="overwriteExistingJobs" value="true" />
<property name="triggers">
<list>
<ref bean="Emailschedule trigger" />
</list>
</property>
</bean>
First of all, I can't use Spring's #Transactional annotation. I have to use exactly JTA which in out EJB-container. Currecntly I'm using JBoss AS 7.0 Web-Profile. So what I need to do is configure Hibernate's session factory to correctly work with JTA-transaction inside the Spring's Envirnoment. My current configuration:
piece of the context.xml configuration:
<tx:annotation-driven/>
<tx:jta-transaction-manager />
<!-- Some other beans -->
<bean id="userTransaction" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/UserTransaction"></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.badmitrii.db.entity.Employee</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="userTransaction" ref="userTransaction"></property>
</bean>
DAO-method:
public Player getPlayerById(Integer id){
try {
userTransaction.begin();
} catch (Exception e) { }
//Here is obtaining a Criteria object and setting Restrictions
try {
userTransaction.commit();
} catch (Exception e) { }
return (Player) criteria.uniqueResult();
}
But, I got the following excpetion when I was trying to get Session in the DAO method:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:134)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:1024)
com.badmitrii.db.dao.EmployeeDAOImpl.getEmployeeById(EmployeeDAOImpl.java:34)
com.badmitrii.EmployeeListController.getEmployeeById(EmployeeListController.java:42)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:483)
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:734)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
How to configure it correctly?
First of all remove the declaration for JtaTransactionManager as that is already provided by <tx:jta-transaction-manager />.
Next there is no reason why you wouldn't be able to use #Transactional in a JTA environment that is the whole point of declarative tx management.
You should wire the configured jta transactionmanager to the LocalSessionFactoryBean to switch out the used CurrentSessionContext.
<tx:annotation-driven/>
<tx:jta-transaction-manager />
<!-- Some other beans -->
<bean id="userTransaction" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/UserTransaction"></property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jtaTransactionManager" ref="transactionManager" />
<property name="annotatedClasses">
<list>
<value>com.badmitrii.db.entity.Employee</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
Then in your cod eyou can simply do something like this
#Transactional
public Player getPlayerById(Integer id){
//Here is obtaining a Criteria object and setting Restrictions
return (Player) criteria.uniqueResult();
}
Update:
For JBoss the <tx:jta-transaction-manager /> doesn't work due to fact that the TransactionManager for JTA is registered in JNDI under the name java:jboss/TransactionManager instead of one of the well-known names. You will need to declare the JtaTransactionManager bean yourself and remove the <tx:jta-transaction-manager /> element. For the lookup you need to specify the transactionManagerName or do a JNDI lookup yourself.
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="java:jboss/TransactionManager" />
</bean>
The UserTransaction is registered under the default name so you can omit the injection of it in the JtaTransactionManager as it will do the lookup itself.
i want to use Hikari CP in my Spring 4.0.3 context but seems i am missing something.
My bean configuration looks like:
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSource.driverClassName">${database.driver}</prop>
<prop key="dataSource.jdbcUrl">${database.database.jdbc.url}</prop>
<prop key="dataSource.port">${database.port}</prop>
<prop key="dataSource.databaseName">${database.name}</prop>
<prop key="dataSource.user">${database.user}</prop>
<prop key="dataSource.password">${database.password}</prop>
</props>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
but i get an exception:
Caused by: java.lang.IllegalArgumentException: one of either dataSource or dataSourceClassName must be specified
at com.zaxxer.hikari.HikariConfig.validate(HikariConfig.java:655)
at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:66)
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:408)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 15 more
i have tried to configure dataSourceClassName using the HSQL org.hsqldb.jdbc.JDBCDataSource
that way:
<prop key="dataSourceClassName">org.hsqldb.jdbc.JDBCDataSource</prop>
also that way:
<prop key="dataSource.ClassName">org.hsqldb.jdbc.JDBCDataSource</prop>
both times i got the following exception:
Caused by: java.lang.RuntimeException: java.beans.IntrospectionException: Method not found: setPort
at com.zaxxer.hikari.util.PropertyBeanSetter.setProperty(PropertyBeanSetter.java:109)
at com.zaxxer.hikari.util.PropertyBeanSetter.setTargetFromProperties(PropertyBeanSetter.java:61)
at com.zaxxer.hikari.pool.HikariPool.initializeDataSource(HikariPool.java:497)
... 23 more
Caused by: java.beans.IntrospectionException: Method not found: setPort
at java.beans.PropertyDescriptor.<init>(PropertyDescriptor.java:110)
at com.zaxxer.hikari.util.PropertyBeanSetter.setProperty(PropertyBeanSetter.java:97)
... 25 more
Can someone show me a working Hikari CP Spring 4 bean configuration that works with a HSQL DB?
I am not interested in MySql, PG etc. because i know how to get them working. But i can't manage to get it done with HSQL.
Thanks,
Tech used: Java8, Spring 4.0.3, HSQL 2.3.2
one way to get the job done is to provide an instance of a DataSource object:
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<property name="dataSource">
<bean class="org.hsqldb.jdbc.JDBCDataSource">
<property name="url" value="${database.database.jdbc.url}"/>
<property name="databaseName" value="${database.name}"/>
<property name="user" value="${database.user}"/>
<property name="password" value="${database.password}"/>
</bean>
</property>
</bean>
</constructor-arg>
</bean>
for sure there are other solutions.
HTH,
Some of your properties in your example do not need the prefix 'dataSource' if you are using a driver-class.
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg>
<bean class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="driverClassName">${database.driver}</prop>
<prop key="jdbcUrl">${database.database.jdbc.url}</prop>
<prop key="username">${database.user}</prop>
<prop key="password">${database.password}</prop>
</props>
</constructor-arg>
</bean>
</constructor-arg>
</bean>
And port and databaseName can be included in the jdbcUrl.
For a pure Java-config solution, I've used the following (in a class with a #Configuration annotation and included in the component-scan-path):
...
#Bean
public DataSource dataSource() {
return new HikariDataSource(hikariConfig());
}
private HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
config.setDriverClassName(driverClassName);
config.setJdbcUrl(jdbcUrl);
config.setUsername(username);
config.setPassword(password);
return config;
}
...
HTH
Tested under HikariCP 2.3.8 and Hibernate 4.3.8.Final:
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<constructor-arg>
<props>
<prop key="dataSourceClassName">org.postgresql.ds.PGSimpleDataSource</prop>
<prop key="dataSource.user">${database.username}</prop>
<prop key="dataSource.password">${database.password}</prop>
<prop key="dataSource.databaseName">${database.databaseName}</prop>
<prop key="dataSource.serverName">${database.serverName}</prop>
<prop key="connectionTestQuery">SELECT 1</prop>
</props>
</constructor-arg>
</bean>
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg ref="hikariConfig" />
</bean>
For the dataSourceClassName, looks at the popular datasource class names table.
ConnectionTestQuery is required for postgresql as per https://github.com/brettwooldridge/HikariCP/issues/225, shouldn't be needed when using a latest jdbc driver version.
I have the following hibernate config on spring and the server starts after a long time but doesn't connect to DB (no schema on DB). So It was supose to give a error message or create the schema with <prop key="hibernate.hbm2ddl.auto">create</prop>.
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method = "close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://dburl:3306"/>
<property name="user" value="user"/>
<property name="password" value="pass!"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="mappingResources">
<list>
<value>waf/resources/User.hbm.xml</value>
<value>waf/resources/Post.hbm.xml</value>
<value>waf/resources/Position.hbm.xml</value>
<value>waf/resources/Comment.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
<!-- C3P0 CONNECTION POOL -->
<prop key="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>
<prop key="c3p0.acquire_increment">1</prop>
<prop key="c3p0.idle_test_period">100</prop>
<prop key="c3p0.max_size">20</prop>
<prop key="c3p0.max_statements">50</prop>
<prop key="c3p0.min_size">1</prop>
<prop key="c3p0.timeout">10</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
Can you guys help me out?
Hibernate does not create schemas with hbm2ddl.auto. It just creates | creates-drop | etc tables.
Going through the HBM files, you have given as below..
Validate instead of Create
I hope this will not create the DDL. can you please check that? Or is it a typo in question?
Adding to what others have proposed if you are using connection pool (which you are as c3po is mentioned) then while the session Factory is created it will try to use the connection pool backed datasource which in turn will connect to database to pre-create and pool connection. When you say that it does not connect to database - how do you know that ? Is there error in logs? I have seen that if Hibernate session factory is not able to configure itself it throws an error in the logs.