I have a project that i am migrating to use hibernate multitenancy feature. So far, i am injecting the EntityManager like this
@Inject
protected EntityManager em;
With a producer method that looks something like this
@Produces
@Default
@RequestScoped
public EntityManager create() {
String principalName = principal.getName();
String clientIdentifier = getClientIdentifier(principalName);
MultiTenantResolver tenantResolver = (MultiTenantResolver) ((SessionFactoryImplementor) entityManagerFactory).getCurrentTenantIdentifierResolver();
tenantResolver.setTenantIdentifier(clientIdentifier);
EntityManager entityManager = entityManagerFactory.createEntityManager();
logger.debug("=========== created entity manager " + entityManager);
return entityManager;
}
(I am not posting the code of the multitenant implementation classes as i think it is not relevant but i could)
The creation of the EntityManager is working fine, the users are providing their credentials, starting a session and an EntityManager is being created, connected to the right database for each user / request
But when i try to perform a transaction that audits data (via envers with @Autited entities) the transaction cannot commit because of this exception
Caused by: org.hibernate.envers.exception.AuditException: Negative revision numbers are not allowed
at org.hibernate@6.2.6.Final//org.hibernate.envers.internal.revisioninfo.DefaultRevisionInfoGenerator.saveRevisionData(DefaultRevisionInfoGenerator.java:64)
at org.hibernate@6.2.6.Final//org.hibernate.envers.internal.synchronization.AuditProcess.getCurrentRevisionData(AuditProcess.java:138)
at org.hibernate@6.2.6.Final//org.hibernate.envers.internal.synchronization.AuditProcess.executeInSession(AuditProcess.java:115)
at org.hibernate@6.2.6.Final//org.hibernate.envers.internal.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:175)
at org.hibernate@6.2.6.Final//org.hibernate.envers.internal.synchronization.AuditProcessManager$1.doBeforeTransactionCompletion(AuditProcessManager.java:47)
at org.hibernate@6.2.6.Final//org.hibernate.engine.spi.ActionQueue$BeforeTransactionCompletionProcessQueue.beforeTransactionCompletion(ActionQueue.java:1010)
at org.hibernate@6.2.6.Final//org.hibernate.engine.spi.ActionQueue.beforeTransactionCompletion(ActionQueue.java:548)
at org.hibernate@6.2.6.Final//org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:1967)
at org.hibernate@6.2.6.Final//org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:439)
at org.hibernate@6.2.6.Final//org.hibernate.resource.transaction.backend.jta.internal.JtaTransactionCoordinatorImpl.beforeCompletion(JtaTransactionCoordinatorImpl.java:336)
at org.hibernate@6.2.6.Final//org.hibernate.resource.transaction.backend.jta.internal.synchronization.SynchronizationCallbackCoordinatorNonTrackingImpl.beforeCompletion(SynchronizationCallbackCoordinatorNonTrackingImpl.java:47)
at org.hibernate@6.2.6.Final//org.hibernate.resource.transaction.backend.jta.internal.synchronization.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:37)
at org.jboss.as.transactions@29.0.1.Final//org.jboss.as.txn.service.internal.tsr.JCAOrderedLastSynchronizationList.beforeCompletion(JCAOrderedLastSynchronizationList.java:113)
at org.wildfly.transaction.client@3.0.0.Final//org.wildfly.transaction.client.AbstractTransaction.performConsumer(AbstractTransaction.java:236)
at org.wildfly.transaction.client@3.0.0.Final//org.wildfly.transaction.client.AbstractTransaction.performConsumer(AbstractTransaction.java:247)
at org.wildfly.transaction.client@3.0.0.Final//org.wildfly.transaction.client.AbstractTransaction$AssociatingSynchronization.beforeCompletion(AbstractTransaction.java:292)
at org.jboss.jts//com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
at org.jboss.jts//com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:360)
at org.jboss.jts//com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:91)
at org.jboss.jts//com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:162)
at org.jboss.jts//com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1295)
... 125 more
I don't exactly know what can be happening, any pointers ???
Thanks a lot
It turns out that the problem was the sequence that i was using for the audit info table (the header?) for the audit data
According to this article https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#defaults-for-implicit-sequence-generators, the sequence has to comply with some expectations
Once i created the sequence according to that expectations, envers is working fine
This is the query i used:
create sequence audit_info_seq start with 1 increment 1 cache 50;