I have a WAR application as follows:
- JPA/Hibernate 4.1.9.Final
- Hibernate Envers 4.1.9.Final
- Spring 3.1.3.RELEASE
- Spring MVC with JSON/REST
My frontend (web page) makes a request, this leads to a new entity to be saved (this seems to succeed in any case) and then Envers will save corresponding revision info.
Typical deployment is in Tomcat 7, where this works just fine.
For unit testing I spin up a Jetty (8.1.9.v20130131) programmatically, which fails. It baffles me why this behavior is different. I can only imagine that Jetty has a different (lesser standard, perhaps) transaction management on board than Tomcat, but I've failed to pin it down or otherwise work around this.
Below is how I create the web application programmatically:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:applicationContext.xml" })
public class AddCustomerTest {
And:
server = new Server(serverPort);
WebAppContext webAppContext = new WebAppContext();
webAppContext.setContextPath("/webapp");
webAppContext.setWar("src/main/webapp");
webAppContext.setServer(server);
server.setHandler(webAppContext);
Below is the essential exception that I'm getting:
Caused by: org.springframework.transaction.IllegalTransactionStateException: No existing transaction found for transaction marked with propagation 'mandatory'
at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:357)
at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:334)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:105)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at com.sun.proxy.$Proxy115.getByUuid(Unknown Source)
at com.totaalsoftware.incidentmanager.entity.audit.RevisionEntityListener.setUser(RevisionEntityListener.java:53)
at com.totaalsoftware.incidentmanager.entity.audit.RevisionEntityListener.instanceNewRevision(RevisionEntityListener.java:40)
at com.totaalsoftware.incidentmanager.entity.audit.RevisionEntityListener.newRevision(RevisionEntityListener.java:34)
at org.hibernate.envers.revisioninfo.DefaultRevisionInfoGenerator.generate(DefaultRevisionInfoGenerator.java:95)
at org.hibernate.envers.synchronization.AuditProcess.getCurrentRevisionData(AuditProcess.java:124)
at org.hibernate.envers.synchronization.AuditProcess.executeInSession(AuditProcess.java:106)
at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:155)
at org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:662)
... 80 more
My RevisionEntityListener
looks up some user data (from the database, using Hibernate of course). Clearly there's no transaction available, but only when running in Jetty. I've tried marking the RevisionEntityListener
transactional in various ways, to no avail.
Let me know if you need any other info. Your help much appreciated!