使用Hibernate Envers保存实体时审计日志未生成,报非活跃事务异常求助
Hey there, let's break down exactly what's going on here. Your entity saves to the database just fine, but Envers fails to create audit logs and throws that transaction error—this is almost always tied to transaction management mismatches between your main entity persistence and Envers' audit logic. Envers relies entirely on an active database transaction to generate and persist revision records, so if that transaction isn't available when it tries to run, you get this error.
Here are the most common causes and fixes:
1. Transaction scope doesn't cover Envers' audit operations
Envers hooks into Hibernate's entity lifecycle callbacks (like post-persist/post-update) to create audit records. If your transaction is committed before these callbacks run, or if the transaction only covers part of the process, Envers won't have an active transaction to work with.
Fix:
Ensure the entire entity persistence workflow runs within a single active transaction. For example, if you're using Spring:
- Move the
@Transactionalannotation to your service layer method (not just the DAO method) so it wraps the full operation, including Envers' callback logic.
// Bad: Transaction only on DAO method @Repository public class MyEntityDao { @Transactional public void save(MyEntity entity) { entityManager.persist(entity); } } // Good: Transaction on service layer (covers the full save + audit flow) @Service public class MyEntityService { @Transactional public void saveMyEntity(MyEntity entity) { myEntityDao.save(entity); } }
2. Manual transaction management mistakes
If you're handling transactions manually (using EntityManager.getTransaction()), it's easy to mess up the timing—like starting the transaction after persisting the entity, or committing it too early.
Fix:
Always start the transaction before performing any entity operations, and commit only after:
EntityManager em = ...; EntityTransaction tx = em.getTransaction(); tx.begin(); try { em.persist(yourEntity); // Envers runs its audit logic here, within the active transaction tx.commit(); } catch (Exception e) { tx.rollback(); throw new RuntimeException("Failed to save entity", e); }
3. Incorrect transaction propagation behavior (Spring-specific)
If you're using Spring's transaction management, a misconfigured propagation property can cause Envers to lose access to an active transaction. For example, using PROPAGATION_NOT_SUPPORTED or PROPAGATION_REQUIRES_NEW in a way that disconnects the audit logic from the main transaction.
Fix:
Stick to the default PROPAGATION_REQUIRED (or PROPAGATION_MANDATORY if you want to enforce an existing transaction) for methods that trigger entity persistence. Avoid propagation modes that suspend or skip transactions unless you explicitly need them.
4. Database connection auto-commit is enabled
If your database connection is set to auto-commit mode, Hibernate might persist the entity immediately (without an explicit transaction), but Envers still requires an active transaction to create audit records. The auto-commit happens before Envers can run its logic, leaving it with no transaction to use.
Fix:
Disable auto-commit in your persistence configuration. For example, in persistence.xml:
<property name="hibernate.connection.autocommit" value="false"/>
5. Missing Envers configuration or annotations
While your entity saves successfully, double-check that Envers is properly enabled and your entity is marked for auditing:
- Ensure
hibernate.envers.enabledis set totruein your persistence config. - Add the
@Auditedannotation to your entity class (or a parent class if you're using inheritance) to tell Envers to track changes to it.
Example:
@Entity @Audited // Critical for Envers to generate audit logs public class MyEntity { // Entity fields and mappings }
At the end of the day, the core issue is that Envers can't create a revision record without an active transaction. Your entity might save because of auto-commit or a partial transaction, but Envers' audit logic needs that transaction to be alive when it runs. Fixing the transaction scope or management should resolve both the error and missing audit logs.
内容的提问来源于stack exchange,提问作者Khoda

