Scheduler stopped when deadlock happened in Spring Transaction - spring

I've developed a monitoring application that uses Spring-3.0 Hibernate-3.6.5 with SpringHibernateTemplate as DAO. Database SQL Server 2008. This app has long running transaction every day.
#Repository("areaDaoHibernate")
public class AreaDAO implements IArea {
protected HibernateTemplate template = null;
#Autowired #Required
public void setSessionFactory(SessionFactory sessionFactory) {
template = new HibernateTemplate(sessionFactory);
}
// basic dao method
}
This app has some scheduling (implements Runable) via springbeans.
#Component("dailyTask")
#Scope("prototype")
public class DailyTask implements Runnable {
#Override
public void run() {
// running task
}
}
This app uses Apache DBCP for pooling.
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource">
<ref bean="CustodyDataSource" />
</property>
…
</bean>
<bean id = "CustodyDataSource"
class = "org.apache.commons.dbcp.BasicDataSource"
p:driverClassName = "${jdbc1.driverClassName}"
p:url = "${jdbc1.url}"
p:username = "${jdbc1.username}"
p:password = "${jdbc1.password}"
p:maxIdle = "${jdbc1.maxIdle}"
p:maxActive = "${jdbc1.maxActive}"
p:validationQuery = "${jdbc1.validationQuery}"
p:testWhileIdle = "${jdbc1.testWhileIdle}" />
<bean id = "transactionManager"
class = "org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref = "sessionFactory" />
I have problem when this app deadlock, the scheduling stop to run.
The error shows:
2012-12-27 12:57:20,861 WARN (JDBCExceptionReporter:233) - SQL Error: 1205, SQLState: 40001
2012-12-27 12:57:20,862 ERROR (JDBCExceptionReporter:234) - Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
2012-12-27 12:57:20,866 ERROR (DailyTask:238) - org.springframework.dao.CannotAcquireLockException: could not update: [com.btpn.custody.entity.MasterData#00176ed4-b7a2-4da5-a266-ffaab3654050]; SQL [update T_CIF set __UPDATED_DATE=?, STATUS_MD=? where __SID=?]; nested exception is org.hibernate.exception.LockAcquisitionException: could not update: [com.btpn.custody.entity.MasterData#00176ed4-b7a2-4da5-a266-ffaab3654050]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:633)
at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
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:393)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy33.relateWithBranch(Unknown Source)
at com.btpn.custody.bean.DailyTask.relateMasterDataWithBranch(DailyTask.java:1166)
at com.btpn.custody.bean.DailyTask.manualInitial(DailyTask.java:213)
at com.btpn.custody.bean.DailyTask.run(DailyTask.java:197)
at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.exception.LockAcquisitionException: could not update: [com.btpn.custody.entity.MasterData#00176ed4-b7a2-4da5-a266-ffaab3654050]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:107)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2494)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2821)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:113)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:185)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
... 11 more
Caused by: java.sql.SQLException: Transaction (Process ID 55) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:368)
at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2820)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2258)
at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:632)
at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:584)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:546)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:504)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2590)
... 23 more
So my questions:
Should I change connection pool to avoid deadlock problem?
Why my scheduling bean stop run after deadlock happen?

The deadlock occurred in SQL Server. This is neither Spring, Hibernate, the connection pool nor SQL Servers fault. The problem is that your application is locking rows that either your application, or other applications are also trying to lock (in a deadlock manner).
The easiest fix is probably to have a retry-strategy for your job (just retry the whole transaction if it fails). You could also try to figure out exactly which applications / users were involved in the deadlock by looking at the SQL Server logs.

Related

Spring's #Scheduled not running after Hibernate exception

I'm using Hikari CP (5.0.1), Hibernate (5.6.3), hibernate-hikaricp (6.0.0) and I'm getting the connections using HibernateUtil class.
This all works fine, without any issues.
Then I have this #Scheduled method that looks like this:
#Scheduled(fixedDelay = 5000)
public void runCalculations() {
try {
this.calculateKPIs();
} catch (Throwable t) {
logger.error("runCalculations() -> catched exception! - " + t.getMessage(), t);
}
}
private void calculateKPIs() {
Session sessApp = HibernateUtilApp.getSessionFactory().openSession();
Transaction txApp = sessApp.beginTransaction();
Integer val = (Integer) sessApp.createSQLQuery("some query").uniqueResult();
txApp.commit();
sessApp.close();
}
All is running absolutely fine until once upon a time there is a deadlock on the database level - I'm reading data (every 5 seconds) from tables that are sometimes changed by other program (every 30 minutes).
And when this deadlock happens there is this Exception catched and logged:
2022-04-19 08:30:39,760 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (scheduled-task-pool-5) Transaction (Process ID 442) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
2022-04-19 08:30:39,760 ERROR [com.yyy.DW.workers.BW.BWWorker] (scheduled-task-pool-5) BW runCalculations() -> catched exception! - org.hibernate.exception.LockAcquisitionException: could not execute query: javax.persistence.OptimisticLockException: org.hibernate.exception.LockAcquisitionException: could not execute query
at deployment.xxx.war//org.hibernate.internal.ExceptionConverterImpl.wrapLockException(ExceptionConverterImpl.java:277)
at deployment.xxx.war//org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:98)
at deployment.xxx.war//org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1626)
at deployment.xxx.war//org.hibernate.query.internal.AbstractProducedQuery.uniqueResult(AbstractProducedQuery.java:1659)
at deployment.xxx.war//com.yyy.DW.workers.BW.BWWorker.calculateGenericKPI(BWWorker.java:248)
at deployment.xxx.war//com.yyy.DW.workers.BW.BWWorker.runCalculations(BWWorker.java:64)
at jdk.internal.reflect.GeneratedMethodAccessor271.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at deployment.xxx.war//org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at deployment.xxx.war//org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: org.hibernate.exception.LockAcquisitionException: could not execute query
at deployment.xxx.war//org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:120)
at deployment.xxx.war//org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:37)
at deployment.xxx.war//org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at deployment.xxx.war//org.hibernate.loader.Loader.doList(Loader.java:2871)
at deployment.xxx.war//org.hibernate.loader.Loader.doList(Loader.java:2850)
at deployment.xxx.war//org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2682)
at deployment.xxx.war//org.hibernate.loader.Loader.list(Loader.java:2677)
at deployment.xxx.war//org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:338)
at deployment.xxx.war//org.hibernate.internal.SessionImpl.listCustomQuery(SessionImpl.java:2181)
at deployment.xxx.war//org.hibernate.internal.AbstractSharedSessionContract.list(AbstractSharedSessionContract.java:1204)
at deployment.xxx.war//org.hibernate.query.internal.NativeQueryImpl.doList(NativeQueryImpl.java:177)
at deployment.xxx.war//org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1617)
... 14 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Transaction (Process ID 442) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
at deployment.xxx.war//com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:265)
at deployment.xxx.war//com.microsoft.sqlserver.jdbc.SQLServerResultSet$FetchBuffer.nextRow(SQLServerResultSet.java:5471)
at deployment.xxx.war//com.microsoft.sqlserver.jdbc.SQLServerResultSet.fetchBufferNext(SQLServerResultSet.java:1794)
at deployment.xxx.war//com.microsoft.sqlserver.jdbc.SQLServerResultSet.next(SQLServerResultSet.java:1052)
at deployment.xxx.war//com.zaxxer.hikari.pool.HikariProxyResultSet.next(HikariProxyResultSet.java)
at deployment.xxx.war//org.hibernate.loader.Loader.getRowsFromResultSet(Loader.java:1043)
at deployment.xxx.war//org.hibernate.loader.Loader.processResultSet(Loader.java:998)
at deployment.xxx.war//org.hibernate.loader.Loader.doQuery(Loader.java:967)
at deployment.xxx.war//org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:357)
at deployment.xxx.war//org.hibernate.loader.Loader.doList(Loader.java:2868)
... 22 more
But after this exception is raised and catched, the #Scheduled job is never run again (other #Scheduled jobs are fine). The scheduler's task that ran the job (here scheduled-task-pool-5) continues to work and executes other tasks but this one is never run again.
Later in the logs I can see that HikariCP detected and unleaked the leaked connection from this code (as expected).
But I don't really understand why the #Scheduled job is not running again after the catched Exception.
Can anyone help please?

Spring & Hibernate SessionFactory performance issue

I am facing a performance issue with Hibernate sessionFactory.
It is a Spring Boot - Hibernate app with a SessionFactory configured like this
#Bean
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf){
return hemf.getSessionFactory();
}
I have also tried all the different ways described in this question Spring Boot - Handle to Hibernate SessionFactory
My DAO looks like this
#Autowired
private SessionFactory sessionFactory;
#Transactional
public List<Type> findAll() {
return sessionFactory.getCurrentSession().createQuery("from Type").list();
}
When the number of concurrent db requests is bigger than the configured maximumPoolSize(10 in this example) then the application becomes unresponsive.
#RequestMapping(value = "/stress-sessionfactory")
public void stressTest(#RequestParam int threadsCount) {
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < threadsCount; i++) {
final int k = i;
Runnable runnable
= () -> {
List<Type> all = typeDAOHibernate.findAll();
LOG.info("{}:sessionfactory:{} ", k, all.size());
};
Thread t = new Thread(runnable);
threads.add(t);
}
threads.stream().forEach(t -> t.start());
}
You can find a standalone example in github.
The example is configured with maximumPoolSize=10.
So if you just hit
http://localhost:8080/stress-sessionfactory?threadsCount=11 you will get the error I am talking about.
On the other hand a Spring Data repository can easily handle thousands of concurrent requests! (e.g http://localhost:8080/stress-jpa?threadsCount=2000)
I Have tried the same scenario with different datasources(Hikari, Tomcat) , different databases(oracle,h2) and different hibernate
versions( 5.011-Final,v4.3.11-Final) and I always get the same error.
Stacktrace
Exception in thread "Thread-51" Exception in thread "Thread-47" org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:431)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:447)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:277)
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.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at com.example.dao.TypeDAOHibernate$$EnhancerBySpringCGLIB$$e6373e2e.findAll(<generated>)
at com.example.controller.StressController.lambda$stressTest$0(StressController.java:36)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:1700)
at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:48)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:189)
at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:380)
... 9 more
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:48)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:90)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:112)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:230)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:237)
at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:214)
at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:52)
at org.hibernate.internal.SessionImpl.beginTransaction(SessionImpl.java:1512)
at org.hibernate.jpa.internal.TransactionImpl.begin(TransactionImpl.java:45)
... 11 more
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30001ms.
at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:591)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:194)
at com.zaxxer.hikari.pool.HikariPool.getConnection(HikariPool.java:146)
at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
at org.hibernate.internal.AbstractSessionImpl$NonContextualJdbcConnectionAccess.obtainConnection(AbstractSessionImpl.java:386)
at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:87)
... 18 more
[]
I noticed that you are injecting sessionFactory but not using spring-framework transaction features.
If you want to use like this you should close the session you are getting from sessionFactory in dao layer.

JdbcTemplate query close database connection

I use jpa with hibernate. I have following method:
#Transactional
public void myMethod(){
...
firstJDBCTemplateQuery();
secondJDBCTemplateQuery();
...
}
firstJDBCTemplateQuery works, but it closes connection to database. When second secondJDBCTempolateQuery is executed
java.sql.SQLException: Connection is closed exception
is thrown what causes
org.springframework.transaction.TransactionSystemException: Could not roll back JPA transaction ...
My configuration:
EDIT
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="packagesToScan" value="com.emisoft.ami.user.domain" />
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<jpa:repositories base-package="com.emisoft.ami.user.repository"
entity-manager-factory-ref="emf" transaction-manager-ref="transactionManager" />
...
I don't know why 'firstJDBCTemplateQuery' close db connection. How to resolve this problem?
StackTrace:
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Connection is closed.
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:296)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:320)
at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:214)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:140)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.<init>(SQLErrorCodeSQLExceptionTranslator.java:103)
at org.springframework.jdbc.support.JdbcAccessor.getExceptionTranslator(JdbcAccessor.java:99)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:639)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:668)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:676)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:731)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:747)
at org.springframework.jdbc.core.JdbcTemplate.queryForInt(JdbcTemplate.java:782)
at org.springframework.security.provisioning.JdbcUserDetailsManager.findGroupId(JdbcUserDetailsManager.java:373)
at org.springframework.security.provisioning.JdbcUserDetailsManager.addUserToGroup(JdbcUserDetailsManager.java:301)
//////////////////////////////////////////////////This is secondJDBCTemplateQuery///////////
at com.emisoft.ami.user.service.impl.UserServiceImpl.insert(UserServiceImpl.java:42)
///////////////////////////////////////////////////////////////////////////////////////////
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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy46.insert(Unknown Source)
at com.kulig.test.service.PaymentServiceContext.main(PaymentServiceContext.java:28)
Caused by: java.sql.SQLException: Connection is closed.
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.checkOpen(PoolingDataSource.java:185)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.getMetaData(PoolingDataSource.java:244)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:285)
... 29 more
DEBUG: org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator - Unable to translate SQLException with Error code '0', will now try the fallback translator
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction rollback
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Rolling back JPA transaction on EntityManager [org.hibernate.ejb.EntityManagerImpl#76c741]
DEBUG: org.hibernate.engine.transaction.spi.AbstractTransactionImpl - rolling back
DEBUG: org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - re-enabling autocommit
DEBUG: org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - Could not toggle autocommit
java.sql.SQLException: Connection is closed.
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.checkOpen(PoolingDataSource.java:185)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.setAutoCommit(PoolingDataSource.java:327)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.releaseManagedConnection(JdbcTransaction.java:127)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:170)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:209)
at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:106)
at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:539)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:846)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:823)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:493)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:264)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy46.insert(Unknown Source)
at com.kulig.test.service.PaymentServiceContext.main(PaymentServiceContext.java:28)
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.ejb.EntityManagerImpl#76c741] after transaction
DEBUG: org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Releasing JDBC connection
DEBUG: org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Released JDBC connection
ERROR: org.springframework.transaction.interceptor.TransactionInterceptor - Application exception overridden by rollback exception
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [select id from groups where group_name = ?]; SQL state [null]; error code [0]; Connection is closed.; nested exception is java.sql.SQLException: Connection is closed.
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:83)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:605)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:639)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:668)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:676)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:731)
at org.springframework.jdbc.core.JdbcTemplate.queryForObject(JdbcTemplate.java:747)
at org.springframework.jdbc.core.JdbcTemplate.queryForInt(JdbcTemplate.java:782)
at org.springframework.security.provisioning.JdbcUserDetailsManager.findGroupId(JdbcUserDetailsManager.java:373)
at org.springframework.security.provisioning.JdbcUserDetailsManager.addUserToGroup(JdbcUserDetailsManager.java:301)
at com.emisoft.ami.user.service.impl.UserServiceImpl.insert(UserServiceImpl.java:42)
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.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy46.insert(Unknown Source)
at com.kulig.test.service.PaymentServiceContext.main(PaymentServiceContext.java:28)
Caused by: java.sql.SQLException: Connection is closed.
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.checkOpen(PoolingDataSource.java:185)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:312)
at org.springframework.jdbc.core.JdbcTemplate$SimplePreparedStatementCreator.createPreparedStatement(JdbcTemplate.java:1446)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:583)
... 23 more
Exception in thread "main" org.springframework.transaction.TransactionSystemException: Could not roll back JPA transaction; nested exception is javax.persistence.PersistenceException: unexpected error when rollbacking
at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:543)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:846)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:823)
at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:493)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:264)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy46.insert(Unknown Source)
at com.kulig.test.service.PaymentServiceContext.main(PaymentServiceContext.java:28)
Caused by: javax.persistence.PersistenceException: unexpected error when rollbacking
at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:109)
at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:539)
... 9 more
Caused by: org.hibernate.TransactionException: rollback failed
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:215)
at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:106)
... 10 more
Caused by: org.hibernate.TransactionException: unable to rollback against JDBC connection
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:167)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:209)
... 11 more
Caused by: java.sql.SQLException: Connection is closed.
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.checkOpen(PoolingDataSource.java:185)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.rollback(PoolingDataSource.java:322)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.doRollback(JdbcTransaction.java:163)
... 12 more
EDIT
I checked secondJDBCTemplateQuery in stacktrace.
EDIT
I use org.springframework.security.provisioning.JdbcUserDetailsManager
firstJDBCTemplateQuery is createUser(UserDetails user)
secondJDBCTemplateQuery is addUserToGroup(String username, String groupName)
public void createUser(final UserDetails user) {
validateUserDetails(user);
getJdbcTemplate().update(createUserSql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
ps.setBoolean(3, user.isEnabled());
}
});
if (getEnableAuthorities()) {
insertUserAuthorities(user);
}
}
public void addUserToGroup(final String username, final String groupName) {
logger.debug("Adding user '" + username + "' to group '" + groupName + "'");
Assert.hasText(username);
Assert.hasText(groupName);
final int id = findGroupId(groupName);
getJdbcTemplate().update(insertGroupMemberSql, new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setInt(1, id);
ps.setString(2, username);
}
});
userCache.removeUserFromCache(username);
}
EDIT DEBUG RESULT:
Beigin transaction on startup myMethod():
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Creating new transaction with name [com.emisoft.ami.user.service.impl.UserServiceImpl.insert]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Opened new EntityManager [org.hibernate.ejb.EntityManagerImpl#b18ac9] for JPA transaction
DEBUG: org.hibernate.engine.transaction.spi.AbstractTransactionImpl - begin
DEBUG: org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Obtaining JDBC connection
DEBUG: org.hibernate.engine.jdbc.internal.LogicalConnectionImpl - Obtained JDBC connection
DEBUG: org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - initial autocommit status: true
DEBUG: org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction - disabling autocommit
DEBUG: org.springframework.orm.jpa.JpaTransactionManager - Exposing JPA transaction as JDBC transaction [org.springframework.orm.jpa.vendor.HibernateJpaDialect$HibernateConnectionHandle#940dc4]
//////////////////////////////////
firstJDBCTemplateMethod:
//////////////////////////////////
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL update
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [insert into users (username, password, enabled) values (?,?,?)]
DEBUG: org.springframework.jdbc.core.JdbcTemplate - SQL update affected 1 rows
/////////////////////////////////////////
secondJDBCTemplateMethod:
////////////////////////////////////
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL query
DEBUG: org.springframework.jdbc.core.JdbcTemplate - Executing prepared SQL statement [select id from groups where group_name = ?]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
INFO : org.springframework.jdbc.support.SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
DEBUG: org.springframework.jdbc.support.SQLErrorCodesFactory - Looking up default SQLErrorCodes for DataSource [org.apache.commons.dbcp.BasicDataSource#150f6f]
WARN : org.springframework.jdbc.support.SQLErrorCodesFactory - Error while extracting database product name - falling back to empty error codes
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Connection is closed. ///This is the beginning of stacktrace which is located above.
EDIT
PaymentServiceContext :
public class PaymentServiceContext {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"com/kulig/test/service/PaymentServiceTest-context.xml");
UserService userService = context.getBean(UserService.class);
///CREATE POJO OBJECTS credentials and p
...
userService.insert(credentials, p);
}
}
Actually, I have had that same issue recently...
After debugging trough the Hibernate code, I noticed Hibernate 4 calls HibernateJpaDialect.releaseConnection at some point. Comments before suggest that it's only to release the connection, but not to close it since it's the connection used by the transactional context. However, that releaseConnection method does in fact call JdbcUtils.closeConnection(con). The HibernateJpaDialect class responsible is actually part of the spring framework, not hibernate.
In the end, this issue is reported by Spring as a bug (SPR-10395) and should be fixed in release 3.2.3 or above. So in the end, you can use Hibernate 4.2 but you'll have to upgrade spring (orm) in that case:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.3</version>
</dependency>
I think that there is a bug in hibernate. I changed
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.2.5.Final</version>
</dependency>
to
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.12.Final</version>
</dependency>
and it works.
Comparison of 2 different version of HibernateJpaDialect from spring-orm artifact.
Thanks to #Kevin Chabot for pointing this out:
HibernateJpaDialect (spring-orm ver 3.1.4)
public void releaseConnection(Connection con) {
JdbcUtils.closeConnection(con);
}
HibernateJpaDialect (spring-orm ver 3.2.8)
public void releaseConnection(Connection con) {
if (sessionConnectionMethod != null) {
// Need to explicitly call close() with Hibernate 3.x in order to allow
// for eager release of the underlying physical Connection if necessary.
// However, do not do this on Hibernate 4.2+ since it would return the
// physical Connection to the pool right away, making it unusable for
// further operations within the current transaction!
JdbcUtils.closeConnection(con);
}
}
Switching to spring-orm 3.2.3+ solves this problem. Be careful to include spring-orm in your pom.xml explicitly. The common mistake is when pom.xml contains only spring-data and fetches spring-orm thru transitive dependency from spring-data - and than it may be in wrong version.
First of all make sure that you are using the same DataSource for JPA as for your JdbcTemplate. Next wire the DataSource to the JpaTransactionManager.
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
<property name="dataSource" ref="dataSource" />
</bean>
This will make the transaction managed by the same transaction manager (you should only have one transaction manage

Hibernate - Spring, SessionFactory nullPointerException (when calling getCurrentSession())

I try to save my PartageDomain in my database using hibernate session factory, the problem is that in Session session = sessionFactory.getCurrentSession(); a nullPointerException is thrown. My dataSource is well configured, and I can already save/persist other objects with exactly the same way in this project, so I don't khow where the problem comes from.
a snapshot from the console exception :
javax.faces.FacesException: /pages/indexx.xhtml #28,72 listener="#{userMB.saveUserRights}": java.lang.NullPointerException
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:85)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
.....
javax.el.ELException: /pages/indexx.xhtml #28,72 listener="#{userMB.saveUserRights}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:108)
at com.sun.faces.facelets.tag.jsf.core.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxHandler.java:447)
at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:109)
at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:98)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:764)
at javax.faces.component.UIData.broadcast(UIData.java:911)
...
Caused by: java.lang.NullPointerException
at com.stage.dao.PartageDaoImpl.add(PartageDaoImpl.java:35)
at com.stage.beans.UserManagedBean.saveUserRights(UserManagedBean.java:224)
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 com.sun.el.parser.AstValue.invoke(AstValue.java:234)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:102)
... 23 more
here is part of code from the partageDomainImpl class :
#Repository
public class PartageDaoImpl implements PartageDao, Serializable {
#Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
// sessionFactory getter and setter :)
public void add(PartageDomain partageDomain) { System.out.println(partageDomain.getPartageId().getUserDomain().getFirstName()); // I get this
Session session = sessionFactory.getCurrentSession();
// Save
try {
session.persist(partageDomain);
} catch (Exception e) {
session.saveOrUpdate(partageDomain);
}
}
Note that the exception is not caused by the EL langage, in fact I get the object correctly by printing it before calling the getsessionFactory method from which come the exception
in my PartageDomain class I have :
#Entity
public class PartageDomain implements Serializable {
// the PartageDomain properties, getters and setters ....
In fact I'm showing that to you to mention that I'm using annotation to manage dependencies and injections, concerning my session factory, I declared it in my configuration file as
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="${hibernate.config}"
p:packagesToScan="com.stage"/>
I finally found the problem, in fact, it's my partageServiceImpl that has the sessionfactory property managed by spring-hibernate injection system.
In my userManagedBean, I was calling directly the the PartageDaoImpl.add method to add the partageDomain object, the correct thing is to call the PartageServiceImpl.add which has the sessionFactory property, in this whay the currentSession will not be null
I admit that it's a grave error that I made and It costs to me the whole day trying to solving it, so I hope this error will be faslty corrected by the others when seeying the exception that I have.
Just a guess -
It is possible that you have a conflict in your context files.
I think that your #Repository annotated bean is somehow being created in the servlet application context, while <tx:annotation-driven transaction-manager="transactionManager" /> is declared in the root web app context.
In other words the #Transactional works only in the context where tx:annotation-driven is declared.
I suppose that it's possible for some the beans to be autoscanned and created twice making them to exist both in the web application and servlet application contexts, if autoscanning is present in both context configurations.
So the solution may be to check that all beans are created once and in the right places - DAOs in the root context, Controllers in the servlet context etc.
update
Also please note that this code uses catch em all exception handling antipattern and possibly accesses hibernate session after it has raised an exception which is not supported by Hibernate as I know.

cannot initialize Quartz Scheduler in Spring

I'm trying to use Quartz 1.8.5 (and I also tried Quartz2.0 - same issue) with Spring 3.0.0.
However, I do not want to use Spring's utility wrappers for Quartz schedulers, triggers, jobs...
I would like to create all these objects programmatically from my application, just like in a
standalone Java app with no container - for many reasons, but mainly because i have requirements for
dynamic triggers and JobDetails...
So, I have my quartz.properties on the classpath, where I define a JobStoreTX:
org.quartz.scheduler.instanceName: NotificationsScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler.skipUpdateCheck: true
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 3
org.quartz.threadPool.threadPriority: 5
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties: false
org.quartz.jobStore.dataSource: qzDS
org.quartz.jobStore.tablePrefix: QRTZ_
org.quartz.jobStore.isClustered: false
org.quartz.dataSource.qzDS.driver: com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL: jdbc:mysql://localhost:3306/myschema
org.quartz.dataSource.qzDS.user: myuser
org.quartz.dataSource.qzDS.password: mypwd
org.quartz.dataSource.qzDS.maxConnections: 5
Then, I have a simple Initializer class, taken almost as is from example1 of Quartz distribution,
which is using an un-modified HelloJob from the same example:
public class NotificationInitializer {
public void init(){
try {
SchedulerFactory schdFact = new StdSchedulerFactory("quartz.properties");
Scheduler schd = schdFact.getScheduler();
schd.start();
JobDetail jd = new JobDetail("hellojob", Scheduler.DEFAULT_GROUP, HelloJob.class);
Trigger t = TriggerUtils.makeImmediateTrigger(2, 1000);
t.setStartTime(new Date());
schd.scheduleJob(jd, t);
// wait long enough so that the scheduler as an opportunity to run
..........
schd.shutdown(true);
} catch (SchedulerException e) {
.....
}
}
}
And I also have a simple unit test that calls this class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = "classpath:spring/applicationContext.xml")
public class NotificationInitializerTest {
private final static Logger logger = LoggerFactory
.getLogger(NotificationInitializerTest.class);
#BeforeClass
public static void setupClass() {
PropertyConfigurator.configure(Loader
.getResource("spring/log4j.properties"));
PropertyConfigurator.configure(Loader
.getResource("spring/quartz.properties"));
}
#Test
public void testInit() {
NotificationInitializer ni = new NotificationInitializer();
ni.init();
logger.info("NotificationInitializer.init() finished OK");
}
}
And when I run this unit test I'm getting the following errors - see the full stack trace below:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'org.springframework.jdbc.datasource.init.DataSour ceInitializer#0':
Invocation of init method failed; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
Query was empty
Any idea what went wrong?
Also, I am setting up JobStoreTX for now - just to make sure I can get it working,
but eventually I would like to use the JobStoreCMT toplug intoSpring's transaction management.
I could not find any good documentation/examples on how to do that, especially if I don't want to use
Spring's wrappers for schedulers and hardcode all trigger definitions...
Thanks!
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:308)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDeendencies (DependencyInjectionTestExecutionListener.java:109 )
at org.springframework.test.context.support.Dependenc yInjectionTestExecutionListener.prepareTestInstanc e(DependencyInjectionTestExecutionListener.java:75 )
at org.springframework.test.context.TestContextManage r.prepareTestInstance(TestContextManager.java:333)
at org.springframework.test.context.junit4.SpringJUni t4ClassRunner.createTest(SpringJUnit4ClassRunner.j ava:220)
at
.....
Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'org.springframework.jdbc.datasource.init.DataSour ceInitializer#0': Invocation of init method failed; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorEx ception: Query was empty
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:1401)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.doCreateBean(AbstractAu towireCapableBeanFactory.java:512)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.createBean(AbstractAuto wireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.Abstract BeanFactory$1.getObject(AbstractBeanFactory.java:2 90)
at org.springframework.beans.factory.support.DefaultS ingletonBeanRegistry.getSingleton(DefaultSingleton BeanRegistry.java:222)
at org.springframework.beans.factory.support.Abstract BeanFactory.doGetBean(AbstractBeanFactory.java:287 )
at org.springframework.beans.factory.support.Abstract BeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.DefaultL istableBeanFactory.preInstantiateSingletons(Defaul tListableBeanFactory.java:557)
at org.springframework.context.support.AbstractApplic ationContext.finishBeanFactoryInitialization(Abstr actApplicationContext.java:842)
at org.springframework.context.support.AbstractApplic ationContext.refresh(AbstractApplicationContext.ja va:416)
at org.springframework.test.context.support.AbstractG enericContextLoader.loadContext(AbstractGenericCon textLoader.java:84)
at org.springframework.test.context.support.AbstractG enericContextLoader.loadContext(AbstractGenericCon textLoader.java:1)
at org.springframework.test.context.TestContext.loadA pplicationContext(TestContext.java:280)
at org.springframework.test.context.TestContext.getAp plicationContext(TestContext.java:304)
... 25 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorEx ception: Query was empty
at sun.reflect.NativeConstructorAccessorImpl.newInsta nce0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInsta nce(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newI nstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:40 6)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLErro r.java:1030)
at com.mysql.jdbc.SQLError.createSQLException(SQLErro r.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.ja va:3491)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.ja va:3423)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:19 36)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java :2060)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionIm pl.java:2536)
at com.mysql.jdbc.StatementImpl.executeUpdate(Stateme ntImpl.java:1564)
at com.mysql.jdbc.StatementImpl.executeUpdate(Stateme ntImpl.java:1485)
at org.apache.commons.dbcp.DelegatingStatement.execut eUpdate(DelegatingStatement.java:228)
at org.springframework.jdbc.datasource.init.ResourceD atabasePopulator.executeSqlScript(ResourceDatabase Populator.java:157)
at org.springframework.jdbc.datasource.init.ResourceD atabasePopulator.populate(ResourceDatabasePopulato r.java:110)
at org.springframework.jdbc.datasource.init.DataSourc eInitializer.afterPropertiesSet(DataSourceInitiali zer.java:69)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.invokeInitMethods(Abstr actAutowireCapableBeanFactory.java:1460)
at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.initializeBean(Abstract AutowireCapableBeanFactory.java:1398)
...
I recently came across this issue too, (I was using Java7 under Mac OS X), the following worked for me:
first of all, test if the method java.net.InetAddress.getLocalHost() works, if it throws exception like:
Caused by: java.net.UnknownHostException: leo-mbp: nodename nor servname provided, or not known
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$1.lookupAllHostAddr(InetAddress.java:901)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1293)
at java.net.InetAddress.getLocalHost(InetAddress.java:1469)
run the following to workaround it:
scutil --set HostName "localhost"
Hope it's helpful to you.
#blob : you were right on target. After spending hours trying to figure out why the NotificationInitializer was not initialized (as the error message suggested....) I finally tried to remove the Quartz DB initialization script from my Spring config - and everything worked like a charm!
<jdbc:initialize-database data-source="dataSource"
enabled="${database.initschema}">
<jdbc:script location="${database.schemaLoc}" />
<jdbc:script location="${database.seedLoc}" />
<!-- <jdbc:script location="classpath:db/tables_mysql_innodb_1.8.5.sql" /> -->
</jdbc:initialize-database>
I just wish Spring error messages were a bit more specific... :)
Now, I still don't understand why I cannot create the DB tables for Quartz this way - the same scripts works just fine when run directly on the DB. Maybe some weird sequence of startup actions in Spring?
thanks!
Only a guess: Check if you need to specify a connection validation query. Something like
validationQuery="select 1"
Changing "org.quartz.scheduler.instanceId" from AUTO to 10 in quartz.properties file worked for me.

Resources