Hibernate version: 3.1.2
Name and version of the database you are using: Oracle 10g XE
I've run into some trouble using Seam and Hibernate Validations (see
post in Seam Forum). And Gavin recommended asking emmanuel in the hibernate forum - so here I am.
In summary:
Quote:
The problem is that the ValidationInterceptor only runs *after* the EJB txn has already started, so any changes to managed objects (as opposed to new or detached objects) will end up being flushed when the txn ends.
To work around this problem I set the flushMode of the entity manager to NEVER in a JSF ActionListener, so that on form submission if the validation fails no flush is attempted.
Like so:
Seam managed bean (WizardAction.java):
Code:
...
public void checkValidation(ActionEvent ae) {
org.hibernate.ejb.EntityManagerImpl e = (org.hibernate.ejb.EntityManagerImpl) em ;
e.getSession().setFlushMode(FlushMode.NEVER);
}
@End ( ifOutcome = "saved" )
@IfInvalid( outcome = Outcome.REDISPLAY)
@TransactionAttribute(REQUIRED)
public String save() {
em.persist( selection );
em.flush() ;
return "saved";
}
...
View code (TestPage2.xhtml):
Code:
<h:commandLink action="#{wizard.save}" actionListener="#{wizard.checkValidation}">
Save
</h:commandLink>
However, the flush mode seems to be reset to AUTO when the transaction starts on the form submission action method. Is this the expected behaviour and if so, is there any way to prevent this from happening? Any help would be gratefully received and if further information is needed I'm happy to post it here.
Thanks in advance, Peter.
Debug log / stack trace:Code:
26-04 10:16:33 DEBUG [Lifecycle] >>> Begin web request
26-04 10:16:33 DEBUG [Component] instantiating Seam component: org.jboss.seam.core.manager
26-04 10:16:33 DEBUG [Manager] Restoring conversation with id: 2
26-04 10:16:33 DEBUG [Contexts] found in application context: org.jboss.seam.core.init
26-04 10:16:33 DEBUG [SeamPhaseListener] After restore view, conversation context: ConversationContext(2)
26-04 10:16:33 DEBUG [LoggedInPhaseListener] afterPhase view id: /TestPage2.xhtml
26-04 10:16:33 DEBUG [LoggedInPhaseListener] Page /TestPage2.xhtml does not require authentication.
26-04 10:16:33 DEBUG [SeamVariableResolver] resolving name: selection
26-04 10:16:33 DEBUG [Contexts] found in conversation context: selection
26-04 10:16:33 DEBUG [SeamVariableResolver] resolved name to seam component
26-04 10:16:33 DEBUG [SeamVariableResolver] resolving name: selection
26-04 10:16:33 DEBUG [Contexts] found in conversation context: selection
26-04 10:16:33 DEBUG [SeamVariableResolver] resolved name to seam component
26-04 10:16:33 DEBUG [SeamVariableResolver] resolving name: selection
26-04 10:16:33 DEBUG [Contexts] found in conversation context: selection
26-04 10:16:33 DEBUG [SeamVariableResolver] resolved name to seam component
26-04 10:16:33 DEBUG [SeamVariableResolver] resolving name: wizard
26-04 10:16:33 DEBUG [Contexts] found in conversation context: wizard
26-04 10:16:33 DEBUG [SeamVariableResolver] resolved name to seam component
26-04 10:16:33 DEBUG [Contexts] found in application context: facesContext
26-04 10:16:33 DEBUG [Contexts] found in conversation context: jobsiteEm
26-04 10:16:33 DEBUG [JDBCContext] successfully registered Synchronization
26-04 10:16:33 DEBUG [AbstractEntityManagerImpl] Transaction activated, move to FlushMode AUTO
26-04 10:16:33 DEBUG [SessionImpl] setting flush mode to: AUTO
26-04 10:16:33 DEBUG [Component] selected row: -1
// Me setting the flush mode...
26-04 10:16:33 DEBUG [SessionImpl] setting flush mode to: NEVER
26-04 10:16:33 DEBUG [WizardAction] Set session to flush mode: NEVER
26-04 10:16:33 DEBUG [SeamVariableResolver] resolving name: wizard
26-04 10:16:33 DEBUG [Contexts] found in conversation context: wizard
26-04 10:16:33 DEBUG [SeamVariableResolver] resolved name to seam component
26-04 10:16:33 DEBUG [Contexts] found in application context: facesContext
26-04 10:16:33 DEBUG [Contexts] found in conversation context: jobsiteEm
// txn setting the flush mode...
26-04 10:16:33 DEBUG [AbstractEntityManagerImpl] Transaction activated, move to FlushMode AUTO
26-04 10:16:33 DEBUG [SessionImpl] setting flush mode to: AUTO
26-04 10:16:33 DEBUG [Component] selected row: -1
26-04 10:16:33 DEBUG [ValidationInterceptor] invalid component state: wizard
26-04 10:16:33 DEBUG [ValidationInterceptor] invalid value:page2Value Value 2 must be less than 50 characters long., clientId: null
26-04 10:16:33 DEBUG [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.LocalOnlyContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
26-04 10:16:33 DEBUG [SeamExtendedManagedPersistencePhaseListener] committing transaction
26-04 10:16:33 DEBUG [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.LocalOnlyContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
26-04 10:16:33 DEBUG [CacheSynchronization] transaction before completion callback
26-04 10:16:33 DEBUG [CacheSynchronization] automatically flushing session
26-04 10:16:33 DEBUG [SessionImpl] automatically flushing session
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] flushing session
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] processing flush-time cascades
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] dirty checking collections
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] Flushing entities and processing referenced collections
26-04 10:16:33 DEBUG [AbstractEntityPersister] uk.co.iblocks.jobsite.data.WizardTest.page2Value is dirty
26-04 10:16:33 DEBUG [DefaultFlushEntityEventListener] Updating entity: [uk.co.iblocks.jobsite.data.WizardTest#1]
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] Processing unreferenced collections
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] Scheduling collection removes/(re)creates/updates
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] Flushed: 0 insertions, 1 updates, 0 deletions to 4 objects
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
26-04 10:16:33 DEBUG [Printer] listing entities:
26-04 10:16:33 DEBUG [Printer] uk.co.iblocks.jobsite.data.WizardTest{page2Value=6, id=3, page1Value=3}
26-04 10:16:33 DEBUG [Printer] uk.co.iblocks.jobsite.data.WizardTest{page2Value=4, id=2, page1Value=2}
26-04 10:16:33 DEBUG [Printer] uk.co.iblocks.jobsite.data.WizardTest{page2Value=012345678901234567890123456789012345678901234567890123456789, id=1, page1Value=50}
26-04 10:16:33 DEBUG [Printer] uk.co.iblocks.jobsite.data.WizardTest{page2Value=8, id=4, page1Value=4}
26-04 10:16:33 DEBUG [AbstractFlushingEventListener] executing flush
26-04 10:16:33 DEBUG [JDBCContext] before transaction completion
26-04 10:16:33 DEBUG [SessionImpl] before transaction completion
26-04 10:16:33 DEBUG [CacheSynchronization] transaction after completion callback, status: 4
26-04 10:16:33 DEBUG [JDBCContext] after transaction completion
26-04 10:16:33 DEBUG [SessionImpl] after transaction completion
26-04 10:16:33 ERROR [SeamExceptionFilter] uncaught exception handled by Seam
javax.servlet.ServletException: Could not commit transaction
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:152)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:23)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
26-04 10:16:33 DEBUG [NamingHelper] JNDI InitialContext properties:{java.naming.factory.initial=org.jnp.interfaces.LocalOnlyContextFactory, java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces}
26-04 10:16:33 DEBUG [Lifecycle] After request, destroying contexts
26-04 10:16:33 DEBUG [Lifecycle] flushing business process context
26-04 10:16:33 DEBUG [BusinessProcessContext] no process instance to persist business process state
26-04 10:16:33 DEBUG [Lifecycle] destroying event context
26-04 10:16:33 DEBUG [Contexts] destroying: org.jboss.seam.core.manager
26-04 10:16:33 DEBUG [Lifecycle] flushing server-side conversation context
26-04 10:16:33 DEBUG [Lifecycle] <<< End web request
26-04 10:16:33 ERROR [[Faces Servlet]] Servlet.service() for servlet Faces Servlet threw exception
java.lang.IllegalStateException: Could not commit transaction
at org.jboss.seam.jsf.SeamExtendedManagedPersistencePhaseListener.commit(SeamExtendedManagedPersistencePhaseListener.java:83)
at org.jboss.seam.jsf.SeamExtendedManagedPersistencePhaseListener.afterPhase(SeamExtendedManagedPersistencePhaseListener.java:49)
at org.apache.myfaces.lifecycle.LifecycleImpl.informPhaseListenersAfter(LifecycleImpl.java:519)
at org.apache.myfaces.lifecycle.LifecycleImpl.invokeApplication(LifecycleImpl.java:332)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:84)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:137)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:144)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:23)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:44)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:868)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:663)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by: org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=null:1146042890956/8, BranchQual=null:1146042890956, localId=0:8], status=STATUS_NO_TRANSACTION; - nested throwable: (org.hibernate.validator.InvalidStateException: validation failed for: uk.co.iblocks.jobsite.data.WizardTest)
at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:1283)
at org.jboss.tm.TxManager.commit(TxManager.java:587)
at org.jboss.ejb3.embedded.UserTransactionImpl.commit(UserTransactionImpl.java:90)
at org.jboss.seam.jsf.SeamExtendedManagedPersistencePhaseListener.commit(SeamExtendedManagedPersistencePhaseListener.java:77)
... 28 more
Caused by: org.hibernate.validator.InvalidStateException: validation failed for: uk.co.iblocks.jobsite.data.WizardTest
at org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:104)
at org.hibernate.validator.event.ValidateEventListener.onPreUpdate(ValidateEventListener.java:132)
at org.hibernate.action.EntityUpdateAction.preUpdate(EntityUpdateAction.java:209)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:64)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:243)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:227)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:296)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1009)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:356)
at org.hibernate.transaction.CacheSynchronization.beforeCompletion(CacheSynchronization.java:59)
at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:3056)
at org.jboss.tm.TransactionImpl.beforePrepare(TransactionImpl.java:2614)
at org.jboss.tm.TransactionImpl.commit(TransactionImpl.java:1191)
... 31 more
[/code]