Compound Primary Keys

Hello,

In the Flowable documentation under JPA Requirements there is a bullet point which reads:

... compound primary keys are not supported (@EmbeddedId and @IdClass).

Could someone please elaborate on why compound primary keys are not supported, and what sort of errors could be expected?

Thanks!

Sean

Hi Sean,

In the class JPAEntityMappings you can see that the getIdString method only allows for “simple” id values. So when you would use a compound primary key, this method would throw an error when saving the JPA variable.

Best regards,

Tijs

Hi Tijs,

Thanks for the information. I think my problem must be something else, as I’m not seeing that particular class in my stack trace. I am seeing the following constraint violation error intermittently (maybe once a week):

org.activiti.engine.ActivitiException: Error while flushing EntityManager: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.activiti.engine.impl.variable.EntityManagerSessionImpl.flush(EntityManagerSessionImpl.java:60)
    at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:212)
    at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:138)
    at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:66)
    at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
    at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
    at org.activiti.engine.impl.asyncexecutor.ExecuteAsyncRunnable.run(ExecuteAsyncRunnable.java:69)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1303)
    at org.activiti.engine.impl.variable.EntityManagerSessionImpl.flush(EntityManagerSessionImpl.java:54)
    ... 11 common frames omitted
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
    at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:207)
    at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:45)
    at org.hibernate.persister.collection.AbstractCollectionPersister.insertRows(AbstractCollectionPersister.java:1554)
    at org.hibernate.action.internal.CollectionUpdateAction.execute(CollectionUpdateAction.java:85)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:582)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:456)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39)
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1300)
    ... 12 common frames omitted
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (BREWMASTER.SYS_C0018402) violated

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3665)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1352)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204)
    ... 21 common frames omitted 

The unique constraint in question is a compound primary key, which is why I thought maybe there was a connection.

Does anything jump out at you?

Thanks a lot,

Sean

Hi Sean,

Difficult to say without knowing more about the JPA object being persisted and what “unique constraint (BREWMASTER.SYS_C0018402) violated” means. Do you know the update / insert statement that Activiti is performing when this unique constraint violation is thrown?

Best regards,

Tijs

Hi Tijs,

My JPA model looks like this:

Class A contains a list of class B. This list is annotated with @OneToMany and @OrderColumn. Hibernate is generating an A_B table with (A_ID, B_ORDER, B_ID). Its the insert into this A_B table that is failing, as there is a unique constraint on A_ID, B_ORDER. It seems like Activiti is trying to insert two objects into the list at the same position.

Thanks for your help!

Sean

Hi Sean,

I think it could be that this should be defined as a compound id in JPA.
This kind of use case is a bit more than the simple JPA entity persistence that is available in Flowable / Activiti.
When you are implementing a more advanced JPA data model, then it’s better to work with a separate service and data layer separate from Flowable to my opinion.

Best regards,

Tijs