How to inject SchedulerFactoryBean after Spring 4.3.15 update - java

I am getting the following error after upgrading from Spring 4.3.2 to Spring 4.3.16:
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'schedulerFactory': FactoryBean which is currently in creation returned null from getObject
I am injecting a Quartz Scheduler into one of my beans as follows:
// XML Config
<bean id="schedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" autowire="byName">
<property name="jobFactory">
<bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory"/>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="dataSource" ref="myDS" />
<property name="triggers">
<list>
<ref bean="updateTrigger"/>
<ref bean="queueUpdateTrigger"/>
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">MyQuartzScheduler</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">60000</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.threadPool.threadCount">2</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
</props>
</property>
</bean>
<bean name="UpdateJobUtils" class="app.job.UpdateJobUtils" autowire="byType">
<property name="schedulerFactory" ref="schedulerFactory" />
</bean>
//Bean
public class UpdateJobUtils {
private StdScheduler schedulerFactory;
public void setSchedulerFactory(StdScheduler schedulerFactory) {
this.schedulerFactory = schedulerFactory;
}
...
}
This worked in Spring 4.3.2 up until 4.3.14. I see https://jira.spring.io/browse/SPR-16439 was backported to 4.3.15 so I am wondering if it changes the way I am supposed to use this class?

schedulerFactory had autowire="byName" on its configuration.
I am not sure why that was on there, but removing it seems to have fixed the exception.

Related

How define naming strategy for Hibernate bean using Spring?

I overrided all ImprovedNamingStrategy methods and placed for them breakpoints, but methods were not called in debug mode.
I have only one hibernate factory, so mistake because of other instance is impossible.
I think, the problem is in the key "hibernate.ejb.naming_strategy" or no?
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">
<bean id="sqlSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.${jdbc.dialect}</prop>
<prop key="hibernate.globally_quoted_identifiers=true">true</prop>
<prop key="hibernate.enable_lazy_load_no_trans">false</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.show_sql">{hibernate.show_sql}</prop>
<prop key="hibernate.ejb.naming_strategy">
com.stub.utilities.dao.sql.hibernate.LowerCaseNamingStrategy
</prop>
</props>
</property>
<property name="annotatedClasses"/>
</bean>
</beans>
Pom
<spring.version>4.2.4.RELEASE</spring.version>
<hibernate.core.version>5.0.7.Final</hibernate.core.version>
Hibernate 5 doesn't have any ImprovedNamingStrategy. It uses ImplicitNamingStrategy and PhysicalNamingStrategy interfaces. Strictly speaking, there is the class ImprovedNamingStrategy, for an example, in the Hibernate 5.1. But you can't use it to configure the SessionFactory.
An example to set ImplicitNamingStrategy
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="implicitNamingStrategy">
<bean class="com.github.fluent.hibernate.cfg.strategy.hibernate5.Hibernate5NamingStrategy">
<property name="tablePrefix" value="spring_" />
</bean>
</property>
</bean>
You can use hibernate.implicit_naming_strategy and hibernate.physical_naming_strategy properties as well
<bean id="sqlSessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.implicit_naming_strategy">
com.stub.utilities.dao.sql.hibernate.ImplicitNamingStrategy
</prop>
<prop key="hibernate.physical_naming_strategy">
com.stub.utilities.dao.sql.hibernate.PhysicalNamingStrategy
</prop>
</props>
</property>
<property name="annotatedClasses"/>
</bean>
</beans>
You can refer my other answer about how to implement LowerCaseNamingStrategy
Implementing a NamingStrategy in Hibernate 5 (make autogenerated column names UPPERCASE)

Hibernate : keeping the compatibility for the aggregate functions in hibernate 3.2

Recently I migrate my application from hibernate 3.1 to 3.2.
But I'm getting some cast exception when using aggregate functions (count, avg..).
So, I would like to know how to keep my code's compatibility wiht the new version of hibernate?
Like making some change in the config of the sessionfactory bean:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
singleton="true">
<property name="mappingResources">
<list>
<value>
hibernate/mapping/Domain.hbm.xml
</value>
<value>
hibernate/mapping/EpAttributeDef.hbm.xml
</value>
<value>
hibernate/mapping/Activity.hbm.xml
</value>
....
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.OracleDialect
</prop>
<prop key="hibernate.cache.provider_class">
org.hibernate.cache.HashtableCacheProvider
</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
A solution is provided here:
https://searchcode.com/codesearch/view/30527532/
So the class of the sessionFactory bean would be ClassicLocalSessionFactoryBeanHibernate31 instead of LocalSessionFactoryBean.

Quatz job not getting triigered in spring with Quartz

below is my quatz integration with Spring but it is not working i.e. Job is not getting triggered . I can see quartz is checking MySQL database in few MS so that means connection with MYSQL is fine and also records are getting inserted in tables but Sysout mentioned in below class is not coming in console. please advice what could be root cause -
from Spring config XML
<bean id="myTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="50" />
<property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>
<bean id="exampleBusinessObjectJobTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail">
<bean name="exampleBusinessObjectJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="name" value="exampleBusinessObjectJob"/>
<property name="jobClass" value="com.aexp.mars.job.ExampleJob"/>
</bean>
</property>
<property name="cronExpression" value="0 */1 * * * ?"/>
</bean>
<bean id="exampleBusinessObjectJob" class="com.aexp.mars.job.ExampleJob">
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="autoStartup" value="true"/>
<property name="triggers">
<list>
<ref bean="exampleBusinessObjectJobTrigger" />
</list>
</property>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceName">MARS_SCHEDULER</prop>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<prop key="org.quartz.scheduler.instanceId">10000</prop>
<prop key="org.quartz.scheduler.instanceId">600000</prop>
<prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
<prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
<prop key="org.quartz.threadPool.threadCount">3</prop>
<prop key="org.quartz.threadPool.threadPriority">5</prop>
<prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
<prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreTX</prop>
<prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
<prop key="org.quartz.jobStore.useProperties">false</prop>
<prop key="org.quartz.jobStore.dataSource">marsDS</prop>
<prop key="org.quartz.jobStore.tablePrefix">QRTZ_</prop>
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">15000</prop>
<prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">20</prop>
<prop key="org.quartz.dataSource.marsDS.driver">com.mysql.jdbc.Driver</prop>
<prop key="org.quartz.dataSource.marsDS.URL">{server_url}</prop>
<prop key="org.quartz.dataSource.marsDS.user">{user_name}</prop>
<prop key="org.quartz.dataSource.marsDS.password">{password}</prop>
<prop key="org.quartz.dataSource.marsDS.maxConnections">10</prop>
<prop key="org.quartz.dataSource.marsDS.validationQuery">select 1</prop>
<prop key="org.quartz.plugin.shutdownHook.class">org.quartz.plugins.management.ShutdownHookPlugin</prop>
<prop key="org.quartz.plugin.shutdownHook.cleanShutdown">false</prop>
</props>
</property>
<property name="taskExecutor" ref="myTaskExecutor" />
<property name="jobFactory">
<bean class="com.aexp.mars.job.MarsSpringBeanJobFactory"/>
</property>
</bean>
**Java class - **
public class ExampleJob {
private static final Logger LOG = LoggerFactory.getLogger(ExampleJob.class);
protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException {
System.out.println("Job is running");
LOG.info("Job ran");
}
public void execute(JobExecutionContext ctx) throws JobExecutionException {
System.out.println("Job#1 is running");
LOG.info("Job ran");
}
}
Got the scenario . I changed the value of cron expression to run it in every 1 minute but it was still set to my previous value (i.e. early morning 3 AM) . i added below property and then new cron expression startd working ..
<property name="overwriteExistingJobs" value="true"/>

How to configure Hibernate, Spring and Apache dbcp for connection pooling?

I have a problem integrating Spring, Hibernate, and Apache DBCP. I have used the DBCPConnectionProvider from here.
I have the following xml configuration for the above said.
<context:component-scan base-package="com.my.app"/>
<tx:annotation-driven/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan">
<list>
<value>com.my.app.model</value>
</list>
</property>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/app</prop>
<prop key="hibernate.connection.username">foo</prop>
<prop key="hibernate.connection.password">bar</prop>
<prop key="hibernate.connection.provider_class">org.hibernate.connection.DBCPConnectionProvider</prop>
<!-- Connection pooling related properties -->
<prop key="hibernate.dbcp.initialSize">8</prop>
<prop key="hibernate.dbcp.maxActive">20</prop>
<prop key="hibernate.dbcp.maxIdle">5</prop>
<prop key="hibernate.dbcp.minIdle">0</prop>
<prop key="hibernate.dbcp.maxWait">10000</prop>
<prop key="hibernate.dbcp.minEvictableIdleTimeMillis">180000</prop>
<prop key="hibernate.dbcp.timeBetweenEvictionRunsMillis">180000</prop>
<prop key="hibernate.dbcp.testWhileIdle">true</prop>
<prop key="hibernate.dbcp.testOnReturn">true</prop>
<prop key="hibernate.dbcp.validationQuery">select 1</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
When the database schema i.e. app is empty two tables will be created in mysql. But I am getting NullPointerException in the getConnection() method of the DBCPConnectionProvider that I mentioned. That means the dataSource is not instantiated. I think I have configured everything in the xml. What am I missing. How do you configure DBCP version 1.4 with Spring and Hibernate? Please provide your insights.
Here is the stack trace:
Caused by: java.lang.NullPointerException
at org.hibernate.connection.DBCPConnectionProvider.getConnection(DBCPConnectionProvider.java:209)
at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:417)
at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:119)
at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:57)
at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1326)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:555)
... 82 more
Don't do it like that. Configure the datasource you want to use in Spring as well as Hibernate. Ditch the hibernate.dbcp and hibernate.connection properties.
<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/app"/>
<property name="username" value="foo"/>
<property name="password" value="bar"/>
// Other DBCP properties here
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"
<property name="packagesToScan">
<list>
<value>com.my.app.model</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="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
Just add the dataSource property to your AnnotationSessionFactoryBean as dependency and done. Note you don't need the configurationClass property as it is already annotation based.
A tip I wouldn't suggest using Commons-DBCP anymore as a datasource instead take a look at HikariCP as a better datasource implementation.
For more information in integrating/configuring Hibernate with Spring I suggest this section of the Reference Guide.

spring hibernate configuration using resource_local or jta by default?

may i know as my configuration is done directly on applicationContext.xml, i do not have persistence.xml . by default this is resource_loca or jta? do i need to add extra parameter if i want to use jta?
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>oracle.jdbc.driver.OracleDriver</value>
</property>
<!-- xdb is defined by running the hsqldb as xdb (see above) -->
<property name="url">
<value>jdbc:oracle:thin:#theserver:1521:appsdb</value>
</property>
<property name="username">
<value>test</value>
</property>
<property name="password">
<value>test</value>
</property>
</bean>
<bean id="annotatedsessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="packagesToScan" value="com.company.x.model" >
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.use_sql_comments">true</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.c3p0.min_size">5</prop>
<prop key="hibernate.c3p0.max_size">20</prop>
<prop key="hibernate.c3p0.timeout">1800</prop>
<prop key="hibernate.c3p0.max_statements">50</prop>
<prop key="hibernate.cache.provider_class">
com.company.x.services.ExternalEhCacheProvider
</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
RESOURCE_LOCAL only applies to JPA EntityManager, not to a Hibernate SessionFactory. Hibernate's Spring integration is rather smoother than it is with JPA, and so the only thing that determines the transactional behaviour is which transaction manager you use with it (either HibernateTransactionManager or JtaTransactionManager). It'll work with either one without you having to explicitly configure the SessionFactory.

Categories

Resources