2012-02-02 4 views
1

Enversを使用して、埋め込まれたコンポーネントと多対多の関係を監査したいが、MappingExceptionでComponentTypeがサポートされていません。これは、関連するスタックトレースの一部です:Enversリファレンスを読むEnversを使用して多対多の関係を監査するのが難しい

Caused by: org.hibernate.MappingException: Type not supported: org.hibernate.type.ComponentType 
     at org.hibernate.envers.configuration.metadata.IdMetadataGenerator.addIdProperties(IdMetadataGenerator.java:74) 
     at org.hibernate.envers.configuration.metadata.IdMetadataGenerator.addId(IdMetadataGenerator.java:105) 
     at org.hibernate.envers.configuration.metadata.AuditMetadataGenerator.generateFirstPass(AuditMetadataGenerator.java:413) 
     at org.hibernate.envers.configuration.EntitiesConfigurator.configure(EntitiesConfigurator.java:101) 
     at org.hibernate.envers.configuration.AuditConfiguration.<init>(AuditConfiguration.java:103) 
     at org.hibernate.envers.configuration.AuditConfiguration.getFor(AuditConfiguration.java:135) 
     at org.hibernate.envers.event.EnversIntegrator.integrate(EnversIntegrator.java:63) 
     at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:295) 
     at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1737) 
     at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:76) 
     at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905) 

、Enversは私が何をしようとしている を扱うことができることが表示されます。文献によれば:あなたは@MappedSuperclassまたは組み込みコンポーネントに継承されたいくつかのフィールド/プロパティの監査の動作を変更したい場合は

、あなたは、サブタイプや使用上の@AuditOverride(s)は注釈を適用することができますコンポーネントのサイト。

私の関連団体です。 @AuditOverrideをクラスレベルで使用しようとした場所を確認すると、埋め込みコンポーネントの監査を防ぐことができます。また、フィールド自体にアノテーションを使用してみました。どちらも違いはありませんでした。ここで

@Audited 
// @AuditOverride(name = "pk", isAudited = false) <===== Didn't help 
@Table(name = "user_role") 
@javax.persistence.Entity 
@AssociationOverrides 
(
    { 
    @AssociationOverride 
     (name = "pk.user", joinColumns = @JoinColumn(name = "id")), 
    @AssociationOverride 
     (name = "pk.role", joinColumns = @JoinColumn(name = "id")) 
    } 
) 
public class UserRole extends Entity<UserRole> 
{ 
    private static final long serialVersionUID = 1L; 

    private Date expirationDate; 
    private UserRolePk pk = new UserRolePk(); 

    public UserRole() {} 

    // @AuditOverride(name = "pk", isAudited = false) <== Didn't help 
    @EmbeddedId 
    public UserRolePk getPk() { return pk; } 

    @Transient 
    public User getUser() { return getPk().getUser(); } 

    @Transient 
    public Role getRole() { return getPk().getRole(); } 
... 
} 

は、ユーザエンティティです:

@Audited 
@Table(name = "applicationuser") 
@javax.persistence.Entity 
public class User extends Entity<User> 
{ 
    private static final long serialVersionUID = 1L; 
    private String firstName; 
    private String lastName; 
    private String email; 
    private Set<UserRole> userRoles = new HashSet<UserRole>(0); 

    @OneToMany(fetch = FetchType.LAZY, cascade=CascadeType.ALL, 
     mappedBy = "pk.user", orphanRemoval = true) 

    public Set<UserRole> getUserRoles() { return userRoles; } 
... 
} 

ここで役割実体です:

@Audited 
@Table(name = "role") 
@javax.persistence.Entity 
public class Role extends Entity<Role> 
{ 
    private static final long serialVersionUID = 1L; 
    private String name; 
    private String label; 
    private Set<UserRole> userRoles = new HashSet<UserRole>(0); 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.role", 
     cascade=CascadeType.ALL, orphanRemoval = true) 

    public Set<UserRole> getUserRoles() { return userRoles; } 
... 
} 

はここに埋め込まれたコンポーネントです:

@Embeddable 
public class UserRolePk implements Serializable 
{ 
    private static final long serialVersionUID = 1L; 

    private User user; 
    private Role role; 

    @ManyToOne 
    public User getUser() { return user; } 

    @ManyToOne 
    public Role getRole() { return role; } 
... 
} 

そして最後に、ここで私のベースがあります完全性のために、

@MappedSuperclass() 
public abstract class Entity<X extends Entity<X>> 
    implements Comparable<X>, Serializable 
{ 
    private static final long serialVersionUID = 1L; 
    private Long id; 
    private Timestamp timestamp; 
... 
} 

私はEnversリファレンスを読んでフォーラムを閲覧ますが、情報 はかなりまばらなようだきました。この上の任意のアイデアやポインター?

答えて

1

埋め込み可能なコンポーネントUserRolePkを破棄して、@ JoinColumnなどを使用してこれを解決しました。

public class UserRole extends Entity<UserRole> 
{ 
    private User user; 
    private Role role; 

    public UserRole() {} 

    @ManyToOne(fetch=FetchType.EAGER, optional=false) 
    @JoinColumn(name="userid", referencedColumnName = "id", insertable=false, updatable=false) 
    // XmlTransient used to prevent the following exception when JAXB marshals this into XML: 
    // com.sun.istack.SAXException2: A cycle is detected in the object graph. This will cause 
    // infinitely deep XML: 
    @XmlTransient 
    public User getUser() { return this.user; } 

    @ManyToOne(fetch=FetchType.EAGER, optional=false) 
    @JoinColumn(name="roleid", referencedColumnName = "id", insertable=false, updatable=false) 
    public Role getRole() { return this.role; } 
... 
} 
1

私はEnvers 4.1.3.Finalを使用していますし、それは間違いなく、まだこのバグを持っています@Embeddedコンポーネントとの関係について、それログ監査レコードを正しくデータベースではなく、クエリAPI(forRevisionsOfEntity、私の場合は)単にそれを見ません。変更されたオブジェクトのリビジョン(MOD)が返されますが、埋め込みオブジェクトへの参照を保持する実際のエンティティプロパティを見ると、すべてのリビジョンで常にnullになります。

バグのあるプラグインを緩和するためにマッピングを変更する気がしなかったので、変更された値をネイティブSQL(影響を受けるプロパティー)で照会するための回避策を作成しました。

関連する問題