2011-12-18 10 views
2

エンティティオブジェクトをデータベースから切り離して、非管理対象にする必要があります。私は、EntityManager.detach()メソッドが必要とするメソッドである、EclipseLink永続性プロバイダを使用します。問題は、(実行を取り外すために通過するとき())JBossは例外以下の実行時にスローということである:仕事の罰金を見つけ、マージ、存続のようなエンティティをデタッチする方法(JPA 2.0/EclipseLink/JBoss)

javax.ejb.EJBTransactionRolledbackException: Unexpected Error 
java.lang.NoSuchMethodError: javax.persistence.EntityManager.detach(Ljava/lang/Object;)V 

他の方法。私はHibernateを試して、そのSessionがエンティティをデタッチする特別なメソッドevict()を提供していることを知っていますが、EclipseLinkはそのようなメソッドを持っていません。デタッチ使用の 例():

@PersistenceContext(unitName="Course7-ejbPU") 
protected EntityManager manager; 
(...) 
Query query; 
List<Message> resultList; 
query = manager.createNamedQuery("Message.getUserInputMessageList"); 
query.setParameter("login", login); 
query.setMaxResults(5); 
resultList = query.getResultList(); 
for (Message message : resultList) 
    if (message.getContent().length() > 50) 
    { 
     manager.detach(message);    
     message.setContent(message.getContent().substring(0, 50) + "..."); 
    } 

のpersistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
    <persistence-unit name="Course7-ejbPU" transaction-type="JTA"> 
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
    <jta-data-source>java:/Course7ds</jta-data-source> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 
    <properties> 
     <property name="eclipselink.target-server" value="JBoss"/> 
    </properties> 
    </persistence-unit> 
</persistence> 

プロバイダデータのライブラリは、EARアーカイブに含まれています。 EclipseLinkのバージョンは2.2.0(2.3.2でテスト済み - 違いはありません)、JBossサーバーのバージョン5.1.0です。どんな提案も感謝します。

答えて

3

この例外は、JPA2ではなくJPA1を使用していることを示しています。 JPA2に同梱されているJBossのより新しいバージョンを使用するべきでしょう。

+0

JBossで使用されているJPAのバージョンを確認する方法はありますか?私は永続的なプロバイダのライブラリの問題のバージョンのみと思った。私はこのバージョン(5.1.0.GA)にプロジェクトを展開する必要があるため、JBossの最新バージョンを使用することはできません。 – Eadel

+0

ちなみに、プロジェクトがGlassfish 3.1.1にデプロイされたとき、detach()は正常に動作しました。しかし、EclipseLinkライブラリは必要ありませんでした。 – Eadel

+0

ejb3-persistence.jarはJBoss 5.1がjavax.persistenceクラスを含むものです。それを開くと、JPA1で導入されたクラスが含まれていないことがわかります。それに含まれるライセンスファイルには、JPA 1.0が含まれているEnterprise JavaBeans v.3.0も含まれています。 –

2

JPA 2.0クラスでコードをコンパイルしましたが、JPA 1.0で実行します。これは、JVMがデタッチメソッドを見つけられない理由です。

あなたのコメントに反応して、いいえ、デタッチメソッドはJPA 1.0ユーザーにとって役に立たないわけではありません。まだ作成されていないだけです。ただし、エンティティマネージャでclean()を呼び出すと、すべてのL1キャッシュを消去できます。これにより、すべての管理対象エンティティがデタッチされます。

エンティティをデタッチするには、永続性プロバイダ固有のコードを使用できます。 エンティティマネージャがまだ機能を提供していないこと、jpaプロバイダがまだその機能を実装していないからではありません。

少しコードをjpaプロバイダに結合できる場合: emLinkgetエンティティマネージャの実装を返すem.getDelegate()メソッドを呼び出すことができます(戻り値をデバッグしてキャスト)。おそらくあなたのエンティティを切り離す可能性があります。 このメソッドは、evict()のHibernateの場合、detach() - >という名前ではありません。

+0

org.eclipse.persistence.sessions.Sessionクラスで同様のメソッドを探しましたが、どのオブジェクトがEntityManager.getDelegateから返されますか)メソッドを使用していましたが、適切なものは見つかりませんでしたが、エンティティオブジェクトを手動でコピーすることで問題を解決しました(新規のオペレータnewを作成し、すべてのプロパティを1つずつコピーしています)しかし、かなりunpretty :)あなたの説明をありがとう! – Eadel

+0

実際には、返されたデリゲートは、(JPA 2.0で途中で使用されている)デタッチメソッドを提供するorg.eclipse.persistence.internal.jpa.EntityManagerImplによって実装されるJpaEntityManagerです。呼び出し((JpaEntityManager)em.getDelegate())。detach(entity)はおそらくうまくいくでしょう。 –

+0

残念なことに、この方法でも同じエラーが発生しました:javax.ejb.EJBTransactionRolledbackException:予期しないエラーjava.lang.NoSuchMethodError:org.eclipse.persistence.jpa.JpaEntityManager.detach(Ljava/lang/Object;)V – Eadel