次のようなマッピングを実現したい。私はいくつかの製品と記事を持っています。1 つの製品には多くの記事が関連付けられています。さらに、この関係にはリターン コードなどの特別なプロパティがあります。したがって、関連テーブルは次のようになります。
Product_FK | Article_FK | return code
1 | 1 | 0
1 | 1 | 1
1 | 2 | 1
現時点で、私はこれを 2 つの協会で認識しています。「一(製品)対多(関係表)」と「多(実在表)対一(物品)」の関係。
エンティティには休閑地として注釈が付けられています。
製品エンティティ:
@Entity(name = "product")
@Table(name = "PRODUCT")
public class ProductDTO implements BaseEntityDTO {
private static final long serialVersionUID = -6613561719098236228L;
@Id
@Column(name = "PRODUCT_PK")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product_pk_seq")
@SequenceGenerator(name = "product_pk_seq", sequenceName = "product_pk_seq", allocationSize = 1)
protected Long pk;
@OneToMany(cascade = CascadeType.ALL, mappedBy="product")
private List<ProductArticleRelationDTO> product2article = new ArrayList<ProductArticleRelationDTO>();
...
}
ProductArticleRelation エンティティ:
@Entity(name = "productArticleRelation")
@Table(name = "PRODUCT_2_ARTICLE")
public class ProductArticleRelationDTO implements BaseEntityDTO {
private static final long serialVersionUID = -1134854397447263839L;
@Id
@Column(name = "PRODUCT_2_ARTICLE_PK")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "product2article_pk_seq")
@SequenceGenerator(name = "product2article_pk_seq", sequenceName = "product2artikle_pk_seq", allocationSize = 1)
protected Long pk;
@Override
public Long getPk() {
return pk;
}
@Override
public void setPk(long pk) {
this.pk = Long.valueOf(pk);
}
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "PRODUCT_FK")
private ProductDTO product = null;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "ARTICLE_FK")
private ArticleDTO article = null;
@Column
private int returnCode;
...
}
記事エンティティ:
@Entity(name = "article")
@Table(name = "ARTICLE")
public class ArticleDTO implements BaseEntityDTO {
private static final long serialVersionUID = 4397348044985703865L;
@Id
@Column(name = "ARTICLE_PK")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "article_pk_seq")
@SequenceGenerator(name = "article_pk_seq", sequenceName = "article_pk_seq", allocationSize = 1)
protected Long pk;
@Override
public Long getPk() {
return pk;
}
@Override
public void setPk(long pk) {
this.pk = Long.valueOf(pk);
}
@OneToMany(cascade = CascadeType.ALL, mappedBy = "article")
private final List<ProductArticleRelationDTO> product2article = new ArrayList<ProductArticleRelationDTO>();
...
}
注釈が間違っていると確信しています。いくつかの productArticleRelations が追加された製品を永続化したい場合、一意の制約違反が発生します。
for(ProductArticleRelationDTO relation : newProduct2Article) {
product.addProduct2Article(relation);
if(!em.contains(product))
if(product.getPK() == null)
em.persist(product);
else
product = em.merge(product);
else
em.flush();
例外:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: Unique Constraint (BC7_BPV.PK_ARTICLE) violated
Error Code: 1
Query: InsertObjectQuery(bc7.bpv.common.dto.ProductDTO@38f2f)
私がよくわからないのは、productArticleRelation エンティティが必要かどうかです。ということは、「一(製品)対多(アリクル)」という一つの関連付けと、「リターンコード」を属性とする特別な結合テーブルで、このような対応ができるのでしょうか?
編集:忘れていましたが、この関係は双方向でなければなりません。
データベース内のマイ テーブルは次のとおりです (重要な列のみを簡略化するため):
製品:
| PRODUCT_PK | ... |
論文:
| ARTICLE_PK | ... |
PRODUCT_2_ARTICLE:
| PRODUCT_2_ARTICLE_PK | PRODUCT_FK | ARTICLE_FK | RETURNCODE