0

監査目的で Hibernate Envar を使用しています。

これが私のコードと構成です

hibernate.cfg.xml ファイルの構成

<!-- Audit -->
        <listener class="org.hibernate.envers.event.AuditEventListener" type="post-insert"/>
        <listener class="org.hibernate.envers.event.AuditEventListener" type="post-update"/>
        <listener class="org.hibernate.envers.event.AuditEventListener" type="post-delete"/>
        <listener class="org.hibernate.envers.event.AuditEventListener" type="pre-collection-update"/>
        <listener class="org.hibernate.envers.event.AuditEventListener" type="pre-collection-remove"/>
        <listener class="org.hibernate.envers.event.AuditEventListener" type="post-collection-recreate"/>

@Audited で注釈が付けられた 1 つのサンプル エンティティ

@Entity
@Table(name = "Users")
@Audited
public class User extends GenericDomain implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @Column(length=100)
    private String name;
    @Column(length=60)
    private String username;
    @Column(length=130)
    private String password;
    // Getter and setter with more fields
}

ログインしているユーザーの監査をログに記録するための RevisionEntity を作成しました。

@Entity
@Table(name = "REVISIONS")
@RevisionEntity(CustomRevisionListener.class)
public class CustomRevisionEntity {

    @Id
    @GeneratedValue
    @RevisionNumber
    private int id;
    @RevisionTimestamp
    private long audit_timestamp;
    private String username;
    private Long userid;
    // Getter and Setter
}

ここに私のリスナークラスがあります

public class CustomRevisionListener implements RevisionListener {

    public void newRevision(Object revisionEntity) {
        CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity;
        revision.setUsername("username"); //for testing
    }
}

挿入/削除の場合、正常に機能します。

ただし、更新クエリの場合、次の例外が発生します

[ERROR] [http-8080-1 06:05:26] (JDBCExceptionReporter.java:logExceptions:101) Duplicate entry '1085-3' for key 1
[ERROR] [http-8080-1 06:05:26] (AbstractFlushingEventListener.java:performExecutions:324) Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
        at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
        at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:179)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
        at org.hibernate.envers.synchronization.AuditProcess.doBeforeTransactionCompletion(AuditProcess.java:157)
        at org.hibernate.envers.synchronization.AuditProcess.beforeCompletion(AuditProcess.java:164)
        at org.hibernate.transaction.JDBCTransaction.notifyLocalSynchsBeforeTransactionCompletion(JDBCTransaction.java:274)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:140)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy106.deleteSaleRecord(Unknown Source)
        at org.commission.controller.salerecord.SaleRecordController.delete(SaleRecordController.java:753)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
        at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
        at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.commission.util.SessionFilter.doFilter(SessionFilter.java:71)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
        at java.lang.Thread.run(Thread.java:619)
Caused by: java.sql.BatchUpdateException: Duplicate entry '1085-3' for key 1
        at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:2018)
        at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1449)
        at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1723)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
        ... 46 more

すべてのエンティティの一般的な更新コードは次のとおりです

public E update(E entity) {
        getSession().update(entity);
        return entity;
    }
4

1 に答える 1

2

残念ながら、完全なスタック トレースとテーブルの SQL 定義がなければ、ここで何が起こっているのかを言うのは困難です。これらは私がチェックするものです:

  1. 監査テーブルの制約/PK? - 主キーにリビジョン番号とリビジョン タイプが欠落している可能性はありますか - これは、特定のエンティティの同じセッションで更新と削除が発生したために発生しました (カスケード操作と関係があると思いますが、私は今は思い出すことができません)、エンティティ テーブルのリビジョン番号 + PK で、監査テーブルの各行を一意に識別できると思っていました。

  2. デフォルトでは、削除されたエンティティには、元のエンティティのリビジョン番号、リビジョン タイプ、および ID/PK のみが含まれることに注意してください。監査テーブルに NOT NULL 制約がある場合、それが原因で失敗する可能性があります。org.hibernate.envers.store_data_at_deleteプロパティを に設定することで、これを回避できますtrue

于 2012-09-17T20:28:00.560 に答える