2016-08-08 9 views
1

Spring Data JPA AuditingEntityListenerとAuditorAware Beanを使用してJPA監査をセットアップしました。私が望むのは、あらかじめ定義された識別子を持つエンティティでも監査人の詳細を永続させることです。 me.auditing.dao.AuditorDetails: - フラッシュする前に、一時的なインスタンスを保存Spring Dataデタッチされたエンティティを永続化するとJPA監査が失敗する

オブジェクト参照、保存されていない一時的なインスタンスを: 問題が事前に定義されたIDを持つJPAエンティティが持続し、フラッシュされたとき、それは、監査人の詳細を永続化することができないということです

興味深いのは、生成されたIDを持つエンティティが保存されているときです。すべてが問題ありません。どちらの場合も、エンティティは新しいものです。私はそれが事前に定義し、生成された識別子を持つ両方のエンティティを持っており、監査される必要があります(テストクラスme.auditing.dao.AuditedEntityIntegrationTest)ので、私はこれを実証するためにsample projectを作成したHibernateのコードを掘り、問題を特定することができませんでした。

エンティティは以下のとおりです。

@Entity 
public class AuditedEntityWithPredefinedId extends AuditableEntity { 

    @Id 
    private String id; 

    public String getId() { 
     return id; 
    } 

    public AuditedEntityWithPredefinedId setId(String id) { 
     this.id = id; 
     return this; 
    } 
} 

と:

親クラスがある
@Entity 
public class AuditedEntityWithGeneratedId extends AuditableEntity { 

    @Id 
    @GeneratedValue(generator = "uuid") 
    @GenericGenerator(name = "uuid", strategy = "uuid") 
    private String id; 

    public String getId() { 
     return id; 
    } 

    public AuditedEntityWithGeneratedId setId(String id) { 
     this.id = id; 
     return this; 
    } 
} 

@MappedSuperclass 
@EntityListeners(AuditingEntityListener.class) 
public abstract class AuditableEntity implements Serializable { 

    private static final long serialVersionUID = -7541732975935355789L; 

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    @CreatedBy 
    private AuditorDetails createdBy; 

    @CreatedDate 
    private LocalDateTime createdDate; 

    @ManyToOne(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    @LastModifiedBy 
    private AuditorDetails modifiedBy; 

    @LastModifiedDate 
    private LocalDateTime modifiedDate; 

監査人ゲッターの実装です:

@Override 
public AuditorDetails getCurrentAuditor() { 
    return new AuditorDetails() 
      .setId(null) 
      .setUserId("someUserId") 
      .setDivisionId("someDivisionId"); 
} 

編集2016-08-08:事前定義されたidを持つ新しいエンティティが保存されると、createdByとmodifiedBy AuditorDetailsの2つの異なるインスタンスが取得されます。エンティティが実際に新規でない場合は非常に論理的です。したがって、生成された完全に新しいエンティティは、同じインスタンスのAuditorDetailsを取得し、手動で設定されたIDを持つEntityは取得しません。私はAuditorHandlerに返す前にAuditorAware Beanに監査人の詳細を保存してテストしました。

@Override 
@Transactional 
public AuditorDetails getCurrentAuditor() { 
    AuditorDetails details = new AuditorDetails() 
      .setId(null) 
      .setUserId("someUserId") 
      .setDivisionId("someDivisionId"); 
    return auditorDetailsRepository.save(details); 
} 

それは最もエレガントなソリューションではありませんが、それは今のために働く:今のところ、私は見つけることができる唯一のソリューションですので、[OK]を

答えて

1

は、実際にそのように監査のエンティティに書き込む前にAuditorDetailsを永続化します。

関連する問題