エンティティを永続化し、マージカスケード接続子実体:JPA:私は、次のエンティティクラスとの双方向の1対多の関係持っ
0または1クライアント< - > 0以上の製品の受注を
クライアントエンティティを永続化する場合、(親クライアントへの外部キーが更新されている可能性があるため)関連付けられたプロダクトオーダーエンティティを永続化します。
もちろん、すべての必要なCASCADEオプションはクライアント側で設定されています。
- 製品注文を「1」に作成され、永続化されている:このシナリオでは、既存の製品注文を参照しながら、新たに作成されたクライアントが初めて永続化されている場合でも、それは動作しません。正常に動作します。
- クライアント '2'が作成され、商品オーダーリストに商品オーダー '1'が追加されます。その後、それは永続化されます。動作しません。
私はいくつかのアプリを試しましたが、どれも期待された結果を示していませんでした。以下の結果を参照してください。私はここで関連するすべての質問を読んだが、彼らは私を助けなかった。 GlassFish 3.1.2のApache Derby(JavaDB)インメモリDBに、トランザクションの種類としてEclipseLink 2.3.0、JPA 2.0の純粋なアノテーション、JTAを使用しています。エンティティの関係は、JSF GUIによって管理されます。オブジェクトレベルの関係管理は(永続的なものとは別に)機能し、私はJUnitテストでそれをテストしました。
アプローチ1)NetBeansのクラステンプレートに基づいて "デフォルト"()
クライアント:
@Entity
public class Client implements Serializable, ParentEntity {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToMany(mappedBy = "client", cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH},
fetch= FetchType.LAZY)
private List<ProductOrder> orders = new ArrayList<>();
// other fields, getters and setters
}
productOrderは:
@Entity
public class ProductOrder implements Serializable, ChildEntity {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne // owning side
private Client client;
// other fields, getters and setters
}
一般的な持続性のファサード:
// Called when pressing "save" on the "create new..." JSF page
public void create(T entity) {
getEntityManager().persist(entity);
}
// Called when pressing "save" on the "edit..." JSF page
public void edit(T entity) {
getEntityManager().merge(entity);
}
結果:
警告:システム例外は、EJB ClientFacade法に呼び出し中に発生します。public void javaee6test.beans.AbstractFacade.create(java.langで
(作成)はすぐに、この例外がスローされます.Object) javax.ejb.EJBException:トランザクションが中止されました...
原因: javax.transaction.RollbackException:トランザクションがロールバック用にマークされています。 ...
によって引き起こさ:例外[EclipseLinkの-4002](Eclipseの永続 サービス - 2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException内部 例外:java.sqlの。 SQLIntegrityConstraintViolationException: ステートメントが、重複したキー の値をユニークまたはプライマリキー制約またはユニークなインデックス で識別されたため、「PRODUCTORDER」に「SQL120513133540930」が定義されているため、中止されました。エラーコード:-1 呼び出し:INSERT INTO PRODUCTORDER(ID、CLIENT_ID)VALUES(?、?)bind => [2パラメータがバインドされました]クエリ: InsertObjectQuery(javaee6test.model.ProductOrder [id = 1])... java.sql.SQLIntegrityConstraintViolationException:それはPRO-に定義された 「SQL120513133540930」によって識別されるユニークな または主キー制約または一意のインデックスに重複キー値を引き起こしてしまうため、ステートメントが 中止されたことで引き起こさ
DUCTORDER '。 org.apache.derby.client.am.SqlException:によって引き起こさ...
文が こと-原因を中止されたことがユニークか 主キーCON-straintに重複キー値を引き起こしているだろうか'PRODUCTOR-DER'に定義された 'SQL120513133540930'によって識別される一意のインデックス。
この例外はわかりません。 edit()はうまく動作します。しかし、作成時に商品注文をクライアントに追加したいので、これは不十分です。
アプローチ2))(一般的な持続性ファサードにのみ
変更マージ:
// Called when pressing "save" on the "create new..." JSF page
public void create(T entity) {
getEntityManager().merge(entity);
}
// Called when pressing "save" on the "edit..." JSF page
public void edit(T entity) {
getEntityManager().merge(entity);
}
結果:
オン()を作成し、EclipseLinkのログ出力は言う:
ファイン:INSERT INTO CLIENT(ID、NAME、ADDRESS_ID)VALUES(?、 ?、?) バインド=> [3パラメータバインド]
ただし、製品注文表では「更新」はありません。したがって、関係は確立されていません。一方、edit()はもう一方でうまくいきます。
...
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
結果:
には(作成)、EclipseLinkの両方のエンティティタイプの両方のクライアントと製品注文クラスに
変化に関する
Apporach 3)同上GenerationType.IDENTITYをログ出力は以下の通りです:
Fine:INSERT I NTOクライアント(NAME、ADDRESS_ID)VALUESバインド=> [2つの パラメータバインド]
ファイン(?):値IDENTITY_VAL_LOCAL()
ファイン:( productOrderは(ORDERDATE、CLIENT_ID)値にINSERT? 、?)バインド=> [バインド2つの パラメータ]
ファイン:代わりに、クライアントのリストに追加され、製品の順序に関係をestabilshingの値IDENTITY_VAL_LOCAL()
は、このように、新しいprodcut注文エンティティが作成され、永続化され(!)、そのエンティティとの関係が確立されます。ここでもedit()はうまく動作します。
Apporach 4)アプローチ(2)及び(3)
結果合成:アプローチ(2)と同じ。
私の質問は上記のシナリオを実現する方法はありますか?それはどのように達成できますか?私はJPA(ベンダー固有の解決策なし)にとどまりたいです。
いいえ、これは動作しません。実際には何も変わらない。私は '@JoinColumn(name =" CLIENT_ID "、referencedColumnName =" ID ") 'で試しましたが、動作しませんでした。 – SputNick