0

次の設定のアプリケーションがあります。

Java 6.0 Spring Data JPA 1.1.0.RELEASE Spring Data MongoDB 1.0.2.RELEASE Spring Data MongoDB Cross-Store 1.0.2.RELEASE Hibernate JPA 2.0

このアプリケーションには、JPA PrePersist、PreUpdate、PostPersist、および PostUpdate アノテーションを使用するいくつかのクラスがあります。以下に例を示します。

@Entity
public class Person
{
    private String password;

    @PrePersist
    @PreUpdate
    public void beforeSave()
    {
        if(!Security.isEncrypted(this.password))
        {
            this.password = Security.encrypt(this.password);
        }
    }
}

クロスストア プラグインの AspectJ ウィービングを有効にするとすぐに、Spring アプリケーション コンテキストがエラーでロードに失敗します。

Caused by: javax.persistence.PersistenceException: You can only annotate one callback method with javax.persistence.PrePersist in bean class: org.example.domain.Person
    at org.hibernate.ejb.event.CallbackResolver.resolveCallback(CallbackResolver.java:110)
    at org.hibernate.ejb.event.EntityCallbackHandler.addCallback(EntityCallbackHandler.java:123)
    at org.hibernate.ejb.event.EntityCallbackHandler.add(EntityCallbackHandler.java:61)
    at org.hibernate.ejb.event.JpaIntegrator.integrate(JpaIntegrator.java:151)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:306)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1744)
    at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:94)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:905)
    at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:890)
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:74)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)

エラーの根本的な原因は、Aspect MongoDocumentBacking が追加の PrePersist メソッドと PreUpdate メソッドをエンティティ クラスに織り込んでいることであることがわかりました。クラスにはこれらのアノテーションを持つメソッドがすでにあるため、Hibernate Entity Manager はこれらのクラスの検証に失敗します。

JPA アノテーションを使用する既存のコードを持つアプリケーションでクロスストア プラグインを使用する方法に関するガイダンスはありますか?

4

2 に答える 2

0

@PreUpdate と @PostLoad で同じ問題に直面していました。

これについて springsource で開かれたバグがあります: https://jira.springsource.org/browse/DATAMONGO-519

彼らは以下の解決策を提供しました:

  1. JPA エンティティ イベント リスナー クラスを作成し、PrePersist、PreUpdate などのコードをこれらのリスナーに移動します。
  2. エンティティ クラスに RelatedDocument アノテーションが付けられたフィールドがあるかどうかを最初に検索するようにアスペクトを変更します。
  3. エンティティ クラスに RelatedDocument アノテーションが付けられたフィールドが 1 つ以上ある場合は、クラスに既に EventListeners アノテーションがあるかどうかを確認します。
  4. EventListeners アノテーションがすでに存在する場合は、クロスストア イベント リスナーをリストに追加します。そうでない場合は、EventListeners アノテーションをクラスに追加します。

すべての注釈をエンティティ リスナーに移動したところ、すぐに機能しました。他に何も変更する必要はありません。次のリンクを見てください。エンティティ レベルで同時に追加できるアノテーションは 1 つだけのようですが、多くはエンティティ リスナーを使用して追加できます: http://docs.jboss.org/hibernate/stable/entitymanager /reference/en/html/listeners.html

@Entity
@EntityListeners(ProductEntityListener.class)
public class Product {
}

public class ProductEntityListener {
    @PrePersist
    @PreUpdate
    protected void prePersist(Product entity) {
    }
    @PostLoad
    protected void postLoad(Product entity){
    }
}
于 2012-12-22T12:31:18.043 に答える