Tuesday, July 31, 2012

OneToMany Relation with Non PK Columns

While goofing around @ my office my Boss told me about an issue he was facing while trying to map a OneToMany relation, but instead of using the classical PK on one side and FK on the other side, he wanted to define the relationship between tables with nonKey columns. I still don't know why but this situation reminded me when I was having a hard time playing with 1:1 relations.
Anyway the fact is that we need find a workaround for this, and as is well known if you don't define anything on Hibernate (Annotations), by default is going to use the default values, right?

My approach is simple, by just defining after the OneToMany annotation which columns I'll join, in order to get this Set. Probably my Child table has a PK which doesn't have anything to do with the column I'm using to do the join with the Parent (which is a valid scenario - and BTW is what's happening now) Why don't you give it a try! On my case one of colleagues tried and I got another satisfied customer ;)

Sunday, July 1, 2012

Logging Optimistic Concurrency Exceptions: org.hibernate.StaleObjectStateException and JBPM

When it is running in a cluster configuration, the jBPM synchronizes with the database by using optimistic locking. This means that each operation is performed in a transaction and if, at the end, a collision is detected, then the transaction in question is rolled back and has to be handled with a retry. This can cause org.hibernate.StateObjectStateException exceptions. When this happens, Hibernate will log the exceptions with a simple message: optimistic locking failed

Hibernate can also log the StateObjectStateException with a stack trace:
15:35:07,123 [DispatcherThread] ERROR [AbstractFlushingEventListener] Could not synchronize database state with session
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.pvm.internal.job.TimerImpl#960071]
 at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1769)
 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2412)
 at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2312)
 at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2612)
 at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:96)
 at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
 at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
 at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298)
 at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
 at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
 at org.jbpm.pvm.internal.tx.HibernateSessionResource.prepare(HibernateSessionResource.java:56)
 at org.jbpm.pvm.internal.tx.StandardTransaction.commit(StandardTransaction.java:107)
 at org.jbpm.pvm.internal.tx.StandardTransaction.complete(StandardTransaction.java:64)
 at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:57)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
 at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
 at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
 at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
 at org.jbpm.pvm.internal.jobexecutor.DispatcherThread.acquireJobs(DispatcherThread.java:126)
 at org.jbpm.pvm.internal.jobexecutor.DispatcherThread.run(DispatcherThread.java:67)

To remove these stack traces, set the org.hibernate.event.def.AbstractFlushingEventListener class to FATAL. Do so in log4j by using the following configuration:
log4j.logger.org.hibernate.event.def.AbstractFlushingEventListener=FATAL

Remember, this exception will not affect your process execution!, you can ignore it :)

Source: http://docs.redhat.com/docs/en-US/JBoss_Enterprise_SOA_Platform/5/html/JBPM_Reference_Guide