0

私は2つのオブジェクトの間に非常に基本的な関係を持っています:

@Entity  
public class A {  

  @ManyToOne(optional = false)  
  @JoinColumn(name="B_ID", insertable=false, updatable=true)  
  private StatusOfA sa; 

  getter+setter  
}

@Entity  
public class StatusOfA {  

  @Id    
  private long id; 

  @Column  
  private String status;  

  getter+setter  
}

DB には StatusOfA の限られたセットしかありません。
トランザクションで A を更新します。

@TransactionalAttribute
public void updateStatusOfA(long id) {  
  A a = aDao.getAById(123);  
  if(a != null) {  
    a.getStatusOfA().getId();  //just to ensure that the object is loaded from DB
    StatusOfA anotherStatusOfA = statusOfADao.getStatusOfAById(456);  
    a.setStatusOfA(aontherStatusOfA);  
    aDao.saveOrPersistA(a);  
  }  
}

saveOrPersistA メソッドはここで「a」をマージしています。

私は、Eclipselink が StatusOfA を更新するために 'a' に対してのみ更新を実行することを期待していますが、StatusOfA テーブルに対して新しい挿入を実行しています。Oracle は、一意の制約違反が原因で不平を言っています (Eclipselink が永続化しようとする StatusOfA は既に存在します...)。ここにはカスケードがないため、問題はなく、Hibernate (JPA2) は例外として動作しています。
同じプロジェクトで、私はすでにいくつかのより複雑な関係を作成しましたが、ここでの関係が機能していないことに本当に驚いています。
よろしくお願いします。

4

2 に答える 2

0

仮定: @Id@GeneratedValue(strategy = GenerationType.IDENTITY)


statusOfADao.getStatusOfAById(456) の次の実装を考えてみましょう。

1. id が設定された「proxy」オブジェクトを返します。

 return new StatusOfA(456);

2. 新しいトランザクションでエンティティを返します。

EntityManager em = emf.createEntityManager();em.getTransaction().begin();

StatusOfA o = em.find(StatusOfA.class,456);//em.getReference(StatusOfA.class,456); em.getTransaction().commit(); o を返します。

3. 切り離されたエンティティを返します。

    StatusOfA o = em.find(StatusOfA.class,456);//em.getReference(StatusOfA.class,456);
em.detached(o);
return o;

4. デシリアライズ - シリアライズされたエンティティを返します。

return ObjectCloner.deepCopy(em.find(StatusOfA.class,456));

5. 添付エンティティを返します。

return em.find(StatusOfA.class,456);

結論:

  1. Eclipselink は、実装 N5 のみを「期待どおり」に処理します。
  2. Hibernate は、5 つの実装すべてを「期待どおり」に処理します。
  3. JPA仕様に準拠した動作の分析はありません
于 2011-06-10T14:34:15.897 に答える
0

statusOfADao.getStatusOfAById() は何をしますか?

同じ永続化コンテキスト (同じトランザクションと EntityManager) を使用していますか?

異なる永続コンテキストのオブジェクトを混在させてはならないため、同じ EntityManager を使用する必要があります。

saveOrPersistA は正確に何をしますか? merge() 呼び出しはすべてを正しく解決する必要がありますが、オブジェクトが本当にめちゃくちゃな場合は、期待どおりにすべてをマージするのが難しい場合があります。

A だけをマージしますか、それともそのステータスもマージしますか? ステータスのマージ結果にもステータスを設定してみてください。

于 2011-06-06T15:00:41.023 に答える