I'm trying to upgrade my project and so I've come to transactions. This is how I did it up to now.
<bean id="userServiceTarget" class="com.forgin.service.UserServiceImpl">
<property name="userDAO" ref="userDAO" />
</bean>
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="userServiceTarget" />
<property name="transactionManager" ref="transactionManager" />
<property name="transactionAttributes">
<props>
<prop key="get*">PROPAGATION_SUPPORTS</prop>
<prop key="is*">PROPAGATION_SUPPORTS</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
I changed the transaction attributes like this bellow, but I'm not quite sure how could I link the service with exactly this txAdvice. Cause I generally have different transaction attributes for different services so there I guess should be more than one txAdvice. Is there a way how to say the #Transactional to use this particular txAdvice?
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="is*" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
Alright, I figured out it.. it just came to me. Haha.. I just need to provide additional aop:advisor and aop:pointcut. As simple as that.
<aop:config>
<aop:pointcut id="userOperation"
expression="execution(* com.forgin.service.UserServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation" />
<aop:pointcut id="differentOperation"
expression="execution(* com.forgin.service.DifferentServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdviceDifferent" pointcut-ref="differentOperation" />
</aop:config>
Related
<!-- 引入外部JDBC配置信息 -->
<context:property-placeholder location="classpath:JDBC.properties" />
<!-- 配置C3P0连接池: -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${DriverClass}" />
<property name="jdbcUrl" value="${URL}" />
<property name="user" value="${USER}" />
<property name="password" value="${PASSWORD}" />
<!-- 其他配置 -->
<!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize" value="3"></property>
<!--连接池中保留的最小连接数。Default: 3 -->
<property name="minPoolSize" value="3"></property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="5"></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement" value="3"></property>
<!-- 控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default:
0 -->
<property name="maxStatements" value="8"></property>
<!--maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
<property name="maxStatementsPerConnection" value="5"></property>
<!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
<!-- Hibernate的相关信息 -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 配置Hibernate的其他的属性 -->
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 配置Hibernate的映射文件 -->
<property name="mappingLocations" value="classpath:*.hbm.xml">
</property>
</bean>
<!-- 事务管理: -->
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务通知属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!-- 定义事务传播属性 -->
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="edit*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="new*" propagation="REQUIRED" />
<tx:method name="set*" propagation="REQUIRED" />
<tx:method name="remove*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="change*" propagation="REQUIRED" />
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.fjx.service.*.*(..))"
id="servicePointcut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut" />
</aop:config>
<bean id="roleDao" class="com.fjx.dao.RoleDao">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="roleService" class="com.fjx.service.RoleService">
<property name="roleDao" ref="roleDao"></property>
</bean>
roleService文件如下:
public class RoleService {
private RoleDao roleDao;
public void save(Role role){
roleDao.save(role);
}
public void setRoleDao(RoleDao roleDao) {
this.roleDao = roleDao;
}
}
junit测试类如下:
#Test
public void saveTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
RoleService roleService = (RoleService) applicationContext.getBean("roleService");
Role role = new Role();
role.setRname("11");
role.setRdescription("1111");
int i = 1/0;
roleService.save(role);
Role role1 = new Role();
role1.setRname("11");
role1.setRdescription("1111");
roleService.save(role1);
}
There is an Exception, but the role is saved successfully.It is not rollbacked, i can not find out the question...
I am trying to setup Spring transaction management for Hibernate however, I meet the following issue...
java.lang.IllegalArgumentException: Cannot convert value of type [ac.nz.unitec.service.impl.UserServiceImpl] to required type [org.springframework.aop.Pointcut] for property 'pointcut': no matching editors or conversion strategy found
Here are more details and the Spring configuration
There is an interface called UserService and UserServiceImpl implements the interface.
Spring Configuration:
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="userService"
expression="execution(public * ac.nz.unitec.service.UserService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userService" />
</aop:config>
<!--I also tried the following one but didn't work out either-->
<aop:config>
<aop:pointcut id="userService"
expression="execution(public * ac.nz.unitec.service.impl.UserServiceImpl.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userService" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="exist" />
<tx:method name="add" />
</tx:attributes>
</tx:advice>
<!--Not sure whether the following piece matters as it has duplicate name with the one in aop config-->
<bean name="userService" class="ac.nz.unitec.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
Updated Spring Configuration xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<aop:aspectj-autoproxy />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<value>classpath:jdbc.properties</value>
</property>
</bean>
<bean id="dataSource" destroy-method="close"
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="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>ac/nz/unitec/model/User.hbm.xml</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.format_sql">true</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:pointcut id="userServiceOperation"
expression="execution(* ac.nz.unitec.service.UserService.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="userServiceOperation" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="exist" />
<tx:method name="add" />
</tx:attributes>
</tx:advice>
<bean name="userAction" class="ac.nz.unitec.action.UserAction" scope="prototype">
<property name="userService" ref="userService"/>
</bean>
<bean name="retrieveAction" class="ac.nz.unitec.action.RetrieveAction" scope="prototype">
<property name="userService" ref="userService"/>
</bean>
<bean id="userService" class="ac.nz.unitec.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean name="userDao" class="ac.nz.unitec.dao.impl.UserDaoImpl">
<property name="hibernateTemplate" ref="hibernateTemplate"/>
</bean>
</beans>
Really appreciated for any suggestions, thanks ahead
In the old config file, in aop:config, the aop:pointcut id is userService. However, there is a bean whose name is also userService. I changed the aop:pointcut id to userServiceOperation and it fixed the issue
from a couple of days my application deployed on GAE was in error with the message
ERROR:Context initialization failed
org.springframework.web.context.ContextLoader[ContextLoader.java:215 2015-03-13 16:48:42,389#Request E088823F)
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'transactionManager'
defined in ServletContext resource [/WEB-INF/config/modulo-spring.xml]:
Cannot resolve reference to bean 'fabbricaSessioni'
while setting bean property 'entityManagerFactory';
nested exception is
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'fabbricaSessioni':
Post-processing of the FactoryBean's object failed;
nested exception is java.security.AccessControlException:
access denied ("java.lang.RuntimePermission" "accessClassInPackage.com.sun.proxy")
seems like Google has made some update that fails the spring's proxy creation.
I've searched a lot, but I haven't found anything....
this is my applicationcontext.xml
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory">
<ref local="fabbricaSessioni" />
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.jdbc.GoogleDriver" />
<property name="url" value="jdbc:google:mysql://xxxxx"/>
</bean>
<bean id="fabbricaSessioni" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" scope="singleton">
<property name="dataSource">
<ref bean="dataSource" />
</property>
<property name="persistenceUnitName" value="hib-persistence" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</property>
<property name="jpaProperties">
<props>
[hibernate props]
</props>
</property>
</bean>
<tx:advice id="advice1" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="search*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
<aop:advisor advice-ref="advice1" pointcut="execution(* org.somepackage.*.*(..))" />
<aop:advisor advice-ref="advice1" pointcut="execution(* org.otherpackage.someclass.*(..))" />
</aop:config>
any help is appreciated
I'm new to SSH, and I'm using Spring 4, Hibernate 4 and Struts 2.
When I create a unit testing for a DAO class, I got this exception.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class UserDaoTest {
#Test
public void testAddUserNotExists() {
User user = new User("20116524", "785ee107c11dfe36de668b1ae7baacbb");
userDao.addUser(user);
assertNotNull(userDao.getUserByUsername("20116524"));
}
#Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
/**
* UserDao object to test.
*/
private UserDao userDao;
}
I tried to add following lines to web.xml, but it doesn't work.
Reference: Java / Hibernate - Write operations are not allowed in read-only mode
I believe there's something wrong with my applicationContext.xml, and here's the content:
<!-- Session Factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>emis.accounts.model</value>
</list>
</property>
</bean>
<!-- Transaction -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
There's no configuration about AOP and tx:advice. So I tried to add some lines:
<!-- Transaction -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" read-only="true"/>
<tx:method name="get*" propagation="REQUIRED" read-only="true" />
<tx:method name="find*" propagation="REQUIRED" read-only="true" />
<tx:method name="list*" propagation="REQUIRED" read-only="true" />
<tx:method name="load*" propagation="REQUIRED" read-only="true" />
<tx:method name="save*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="add*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="save" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="update" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="delete" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:aspectj-autoproxy />
<aop:config>
<aop:pointcut id="aopPointcut"
expression="execution(* emis.*.service.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="aopPointcut"/>
</aop:config>
However, I got another exception:
WARNING: Exception thrown from ApplicationListener handling ContextClosedEvent
java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: Root WebApplicationContext: startup date [Thu Mar 20 13:53:51 CST 2014]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:346)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:880)
...
WARNING: Exception thrown from LifecycleProcessor on context close
java.lang.IllegalStateException: LifecycleProcessor not initialized - call 'refresh' before invoking lifecycle methods via the context: Root WebApplicationContext: startup date [Thu Mar 20 13:53:51 CST 2014]; root of context hierarchy
at org.springframework.context.support.AbstractApplicationContext.getLifecycleProcessor(AbstractApplicationContext.java:359)
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:888)
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:841)
...
What should I do? Can anyone help me? Thanks a lot!!
First make up your mind on what you want to use for transactions. XML configuration or annotations #Transactional. Don't try to mix both of them.
If you use #Transactional make sure that your UserDao is annotated with the correct annotations.
If you use XML make sure that you have the ordering inside the tx:advice correct. Currently everything is read-only. The first match wins, as you have a wildcard * on top everything will match that pointcut. Next you don't need the <aop:aspectj-autoproxy /> as you have declared your aspect with an <aop:config /> block.
I'm trying to get a clustered, Spring-managed Quartz environment going and I'm running into problems with the transaction features:
2014-02-06 13:59:00,015 ERROR org.quartz.core.ErrorLogger - Error executing Job (DEFAULT.idleDeviceJob: couldn't begin execution.
org.quartz.SchedulerException: UserTransactionHelper could not lookup/create UserTransaction. [See nested exception: javax.naming.NamingException: Cannot create resource instance]
at org.quartz.ee.jta.UserTransactionHelper$UserTransactionWithContext.<init>(UserTransactionHelper.java:148)
at org.quartz.ee.jta.UserTransactionHelper.lookupUserTransaction(UserTransactionHelper.java:108)
at org.quartz.ee.jta.JTAJobRunShell.begin(JTAJobRunShell.java:101)
at org.quartz.core.JobRunShell.run(JobRunShell.java:164)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:560)
Caused by: javax.naming.NamingException: Cannot create resource instance
at org.apache.naming.factory.TransactionFactory.getObjectInstance(TransactionFactory.java:116)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at org.apache.naming.NamingContext.lookup(NamingContext.java:843)
at org.apache.naming.NamingContext.lookup(NamingContext.java:154)
at org.apache.naming.NamingContext.lookup(NamingContext.java:831)
at org.apache.naming.NamingContext.lookup(NamingContext.java:168)
at org.apache.naming.SelectorContext.lookup(SelectorContext.java:158)
at javax.naming.InitialContext.lookup(InitialContext.java:411)
at org.quartz.ee.jta.UserTransactionHelper$UserTransactionWithContext.<init>(UserTransactionHelper.java:145)
... 4 more
Obviously as I'm running in Tomcat, there is no JNDI registration for the UserTransaction. That said, I can't figure out how to get Quartz to use the existing transactions I've provided in my application context via AOP (or just ignore the transaction stuff as AOP handles it):
<!-- Quartz Scheduler Transaction Propagation -->
<tx:advice id="quartzSchedulerAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" propagation="SUPPORTS" />
<tx:method name="set*" read-only="true" propagation="SUPPORTS" />
<tx:method name="is*" read-only="true" propagation="SUPPORTS" />
<tx:method name="insert*" read-only="false" propagation="REQUIRED"/>
<tx:method name="update*" read-only="false" propagation="REQUIRED"/>
<tx:method name="delete*" read-only="false" propagation="REQUIRED"/>
<tx:method name="schedule*" read-only="false" propagation="REQUIRED" rollback-for="org.quartz.SchedulerException"/>
<tx:method name="pause*" read-only="false" propagation="REQUIRED"/>
<tx:method name="resume*" read-only="false" propagation="REQUIRED"/>
<tx:method name="run*" read-only="false" propagation="REQUIRED"/>
<tx:method name="update*" read-only="false" propagation="REQUIRED"/>
<tx:method name="delete*" read-only="false" propagation="REQUIRED"/>
<tx:method name="toggle*" read-only="false" propagation="REQUIRED"/>
<tx:method name="clone*" read-only="false" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- ensure that the above transactional advice runs for any execution of
an operation defined by the FooService interface -->
<aop:config>
<aop:pointcut id="jdbcDaoPC"
expression="execution(* com.project.repository.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="jdbcDaoPC" />
</aop:config>
<aop:config>
<aop:pointcut id="quartzSchedulerPointcut"
expression="execution(* org.quartz.Scheduler.*(..))" />
<aop:advisor advice-ref="quartzSchedulerAdvice"
pointcut-ref="quartzSchedulerPointcut" />
</aop:config>
I'm using BoneCP as my datasource:
<!-- Row Mapper Beans -->
<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
destroy-method="close">
<property name="driverClass" value="${jdbc.driverClassName}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="idleConnectionTestPeriod" value="60" />
<property name="idleMaxAge" value="240" />
<property name="maxConnectionsPerPartition" value="5" />
<property name="minConnectionsPerPartition" value="2" />
<property name="partitionCount" value="3" />
<property name="acquireIncrement" value="5" />
<property name="statementsCacheSize" value="100" />
<property name="releaseHelperThreads" value="3" />
</bean>
And my Spring scheduler factory configuration is here:
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="classpath:quartz.properties"/>
<property name="dataSource" ref="dataSource"/>
<property name="nonTransactionalDataSource">
<bean class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
</property>
<property name="transactionManager" ref="txManager"/>
<property name="schedulerName" value="ClusteredScheduler"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="autoStartup" value="true"/>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="jobFactory">
<bean class="com.project.scheduling.persistence.AutowiringSpringBeanJobFactory"/>
</property>
<property name="schedulerContextAsMap">
<map>
<entry key="dataSource" value-ref="dataSource" />
<entry key="transactionManager" value-ref="txManager" />
</map>
</property>
<property name="jobDetails">
<list>
<ref bean="shipNoticeJob" />
<ref bean="idleDeviceJob" />
<ref bean="distanceJob" />
<ref bean="deviceMaintenanceJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="shipNoticeCronTrigger" />
<ref bean="idleDeviceTrigger" />
<ref bean="distanceTrigger" />
<ref bean="deviceMaintenanceTrigger" />
</list>
</property>
</bean>
None of the tutorials etc I've been able to find online reference this issue in Tomcat so I'm left assuming theres a configuration step I'm missing...
Well, this one was staring me in the face:
org.quartz.scheduler.wrapJobExecutionInUserTransaction=true
Should have been:
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
Duh.