2012-07-10 31 views
0

我想實現如下映射。我有一些產品和文章。一件產品有許多相關的文章。此外,這個關係具有特殊的屬性,如返回代碼。所以關聯表應該看起來像這樣。由自己的實體實現的「一對多」和「多對一」關聯;違反唯一約束

Product_FK | Article_FK | return code 
     1 | 1  |  0 
     1 | 1  |  1 
     1 | 2  |  1 

目前我已經意識到這與兩個協會。一個(產品)到許多(關係表)「和一個」許多(Realation Table)到一個(Article)「關聯。

的實體被註釋爲休耕:

產品實體:

@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([email protected]) 

什麼我沒那麼很確定的是,如果我需要的productArticleRelation實體。也就意味着它可以處理這類與一個關聯維吾爾的「一個(產品)許多(aricles)」和一個特殊的加入哪個有「返回碼」爲屬性表?

編輯:我忘記了,這種關係應該是雙向的。

我的數據庫中的表是作爲休耕(爲了簡化僅重要的列中示出):

PRODUCT:

| PRODUCT_PK | ... | 

ARTICLE:

| ARTICLE_PK | ... | 

PRODUCT_2_ARTICLE:

| PRODUCT_2_ARTICLE_PK | PRODUCT_FK | ARTICLE_FK | RETURNCODE 
+0

包含SQL日誌,確保您沒有文章的兩個副本 – James 2012-07-12 14:35:42

+0

我在哪裏可以獲得SQL日誌?我正在使用glassfish應用服務器。 – 2012-07-12 22:10:15

+0

好的發現它(在persistence.xml中設置日誌級別)。 – 2012-07-12 22:19:25

回答

1

首要和最重要的:@JoinColumn應在自己方面註釋,即僅在ProductArticleRelationDTO。從ProductArticle中完全刪除它。要映射集合,您應該使用@OneToMany(cascade = CascadeType.ALL, mappedBy="property"),其中屬性是映射屬性的java名稱。在這種情況下,無論是「產品」或「物品」視類。

關於ProductArticleRelationDTO的必要性:你需要它,只要你需要訪問Java中的返回碼。如果它只是一個ManyToMany映射表並將產品直接映射到文章,您可以跳過它,但現在情況並非如此。

如果它不能解決您的問題,請嘗試此操作並發表評論。

+0

我需要訪問返回碼。感謝您的解決方案。我會嘗試。 – 2012-07-10 17:55:25

+0

我有添加表像他們在數據庫中 – 2012-07-10 18:27:53

+0

你是否得到相同的異常? – 2012-07-11 16:50:19