BeanValidation at preUpdate for unchanged entities? [message #1064627] |
Thu, 20 June 2013 09:49 |
Markus KARG Messages: 28 Registered: June 2011 |
Junior Member |
|
|
By incident I noticed that EclipseLink performs BeanValidation on unmodified entities. The following stack trace proofs this. It was crated by a transaction which does nothing but a simple SELECT on an entity with EAGER fetching of relations. Besides the fact that it makes it impossible to load "incorrect" data (so the user cannot correct it in turn) I wonder what actual sense it makes to fire the "preUpdate" event when there actually is nothing to update at all...?! And things are getting even more weird, as the same problem happens even in case of the trasaction being set to rollback only (getUserTransaction().setRollbackOnly() directly after getQueryResultList())!?
javax.validation.ConstraintViolationException: Bean Validation constraint(s) violated while executing Automatic Bean Validation on callback event:'preUpdate'. Please refer to embedded ConstraintViolations for details.
at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.validateOnCallbackEvent(BeanValidationListener.java:90)
at org.eclipse.persistence.internal.jpa.metadata.listeners.BeanValidationListener.preUpdate(BeanValidationListener.java:72)
at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyListener(DescriptorEventManager.java:671)
at org.eclipse.persistence.descriptors.DescriptorEventManager.notifyEJB30Listeners(DescriptorEventManager.java:641)
at org.eclipse.persistence.descriptors.DescriptorEventManager.executeEvent(DescriptorEventManager.java:200)
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChanges(DeferredChangeDetectionPolicy.java:85)
at org.eclipse.persistence.descriptors.changetracking.DeferredChangeDetectionPolicy.calculateChangesForExistingObject(DeferredChangeDetectionPolicy.java:54)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.calculateChanges(UnitOfWorkImpl.java:636)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.commitToDatabaseWithChangeSet(UnitOfWorkImpl.java:1482)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.issueSQLbeforeCompletion(UnitOfWorkImpl.java:3135)
at org.eclipse.persistence.internal.sessions.RepeatableWriteUnitOfWork.issueSQLbeforeCompletion(RepeatableWriteUnitOfWork.java:344)
at org.eclipse.persistence.transaction.AbstractSynchronizationListener.beforeCompletion(AbstractSynchronizationListener.java:157)
at org.eclipse.persistence.transaction.JTASynchronizationListener.beforeCompletion(JTASynchronizationListener.java:68)
at com.sun.enterprise.transaction.JavaEETransactionImpl.commit(JavaEETransactionImpl.java:435)
at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:852)
at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5114)
at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4879)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2039)
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1990)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222)
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
at com.sun.proxy.$Proxy404.getProjects(Unknown Source)
at de.quipsy.application.project.ProjectsResource.propfind(ProjectsResource.java:49)
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.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.VoidVoidDispatchProvider$VoidVoidMethodInvoker._dispatch(VoidVoidDispatchProvider.java:71)
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
at com.sun.jersey.server.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:134)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1469)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at net.java.dev.webdav.interop.WindowsRedirectorPatchResourceFilter.doFilter(WindowsRedirectorPatchResourceFilter.java:205)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:232)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Unknown Source)
[Updated on: Thu, 20 June 2013 09:59] Report message to a moderator
|
|
|
Re: BeanValidation at preUpdate for unchanged entities? [message #1064717 is a reply to message #1064627] |
Thu, 20 June 2013 16:16 |
Chris Delahunt Messages: 1389 Registered: July 2009 |
Senior Member |
|
|
The state of the transaction is checked in the beforeCompletion callback EclipseLink receives, and if it does not have a status of STATUS_ACTIVE or STATUS_PREPARING, it should just return without issuing SQL. So if SQL is being issued, it seems your rollback is not occurring on the transaction associated to the committing UnitOfWork/EntityManager, or it is getting the wrong status back from the TransactionManager. What code are you using to mark the transaction for rollback?
As for the BeanValidationListener being called for every managed instance regardless of changes - this looks like a bug. The BeanValidationListener is overriding the preUpdate method when it should using the preUpdateWithChanges method that is used for JPA preUpdate events. Please file a bug and vote for it.
Because the BeanValidationListener is hardcoded and added to a protected collection, a workaround is more complex. You might need to create a dummy ValidatorFactory class that just ignores validation and specify it using the "javax.persistence.validation.factory" property, and then add in your own BeanValidationListener subclass that overrides the preUpdateWithChanges to call its parent's preUpdate event, and the preUpdate event just return. The code within org.eclipse.persistence.internal.jpa.deployment.BeanValidationInitializationHelper's bootstrapBeanValidation innerclass method shows what needs to be done, but using your own subclass instead. Something like:
for (ClassDescriptor descriptor : session.getProject().getOrderedDescriptors()) {
if (descriptor.isDescriptorTypeNormal()) {
//add only to entities
descriptor.getEventManager().addInternalListener(yourValidationListener);
}
}
Best Regards,
Chris
|
|
|
|
Powered by
FUDForum. Page generated in 0.03239 seconds