2017-05-22 7 views
0

arquillianテストクラスから新しいOrderオブジェクトを永続化しようとしています。 注文エンティティには、主フィールドが4つの構成された主キーを持つOrderDetailエンティティのリストが含まれています。 @IdClassをHibernateとArquillianの組み合わせで使用するCascadeType.Insertは、複合主キーの一部であるManyToOne外部キーオブジェクトに挿入します。

しかし、Hibernateは新しいOrderDetailオブジェクトを挿入しようとしている一方で、それはまた、 ていない新たな Itemオブジェクト(項目がOrderDetailエンティティの主PK分野の一つと@IDで注釈を付けている)を挿入し、これは、その結果DB内のItemテーブルから一意の制約例外。

Item @ OneToManyアノテーション からCascadeTypeを削除し、CascadeType.Refreshも試しましたが、同じ結果が得られましたが、何も変更されませんでした。これは、すべてのケースでCascadeType.Insertを強制的に使用するように機能します。予想通り、私はを使用するときには、を働いた

ではなく@IdClass注釈を@EmbeddedIdしかし、私はそれが@IdClassでは動作しなかった理由を知りたいですか? Hibernateのバグですか?それはJPA 2.1 specificationごとに完全に動作するはずです。

注文エンティティ

@Entity 
@Table(name = "ORDERS") 
public class Orders extends BaseEntity { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "ORDERNO") 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long orderNo ; 

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "order", fetch = FetchType.LAZY) 
    private List<OrderDetail> orderDetailsList ; 

    // setters and getters 
} 

OrderDetailエンティティ

@Entity 
@Table(name = "ORDERDETAILS") 
@IdClass(OrderDetailsPK.class) 
public class OrderDetail extends BaseEntity { 

private static final long serialVersionUID = 1L; 

@Id 
@JoinColumn(name = "ORDERNO", referencedColumnName = "ORDERNO") 
@ManyToOne(optional = false, fetch = FetchType.LAZY) 
private Orders order; 

@Id 
@JoinColumn(name = "ITEMNO", referencedColumnName = "ITEMNO", insertable = false, updatable = false) 
@ManyToOne(cascade = CascadeType.REFRESH,optional = false, fetch = FetchType.LAZY) 
//@Cascade({CascadeType.DETACH}) // I tried this but did not work, it keep try to insert the item. 
private Item item; 

@Id 
@Column(name = "LINETYPE") 
private String lineType; 

@Id 
@Column(name = "PROMITEMNO") 
private String promItemNo; 

Itemエンティティの

@Entity 
@Table(name = "ITEM") 
public class Item extends BaseEntity { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @Column(name = "ITEMNO") 
    private String itemno; 
    // setters and getters 

    @Override 
    public int hashCode() { 
    int hash = 0; 
    hash += (itemno != null ? itemno.hashCode() : 0); 
    return hash; 
    } 

    @Override 
    public boolean equals(Object object) { 
    if (!(object instanceof Item)) { 
     return false; 
    } 
    Item other = (Item) object; 
    System.out.println("Item Equal Method = " + !((this.itemno == null &&  other.itemno != null) || (this.itemno != null && !this.itemno.equals(other.itemno)))); 
    return !((this.itemno == null && other.itemno != null) || (this.itemno != null && !this.itemno.equals(other.itemno))); 
} 

    @Override 
    public String toString() { 
    return "com.unilever.sas.model.entities.masterdata.Item[ itemno=" + itemno + " ]"; 
} 

} 

OrderDetailsPK

public class OrderDetailsPK implements Serializable 
{ 

    private static final long serialVersionUID = 1L; 

    private Long order; 
    private String item; 
    private String lineType; 
    private String promItemNo; 

    public OrderDetailsPK() { 
    } 

    public OrderDetailsPK(Long order, String item, String lineType, String promItemNo) { 
     this.order = order; 
     this.item = item; 
     this.lineType = lineType; 
     this.promItemNo = promItemNo; 
    } 

    public Long getOrder() { 
     return order; 
    } 

    public String getItem() { 
     return item; 
    } 

    public String getLineType() { 
     return lineType; 
    } 


    public String getPromItemNo() { 
     return promItemNo; 
    } 

    @Override 
    public int hashCode() { 
     int hash = 5; 
     hash = 73 * hash + Objects.hashCode(this.order); 
     hash = 73 * hash + Objects.hashCode(this.item); 
     hash = 73 * hash + Objects.hashCode(this.lineType); 
     hash = 73 * hash + Objects.hashCode(this.promItemNo); 
     return hash; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
      return true; 
     } 
     if (obj == null) { 
      return false; 
     } 
     if (getClass() != obj.getClass()) { 
      return false; 
     } 
     final OrderDetailsPK other = (OrderDetailsPK) obj; 
     if (!Objects.equals(this.item, other.item)) { 
      return false; 
     } 
     if (!Objects.equals(this.lineType, other.lineType)) { 
      return false; 
     } 
     if (!Objects.equals(this.promItemNo, other.promItemNo)) { 
      return false; 
     } 
     if (!Objects.equals(this.order, other.order)) { 
      return false; 
     } 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "OrderDetailsPK{" + "order=" + order + ", item=" + item + ", lineType=" + lineType + ", promItemNo=" + promItemNo + '}'; 
    } 

Arquillianテスト

@RunWith(Arquillian.class) 
public class OrdersFacadeTest 
{ 


@Inject 
OrdersFacadeLocal ordersFacade ; 

@Inject  
ItemFacadeLocal itemFacade ; 

@Test 
public void testCreateOrder() throws Exception 
{ 
    Item item = itemFacade.find("20247912"); 
    Orders order = new Orders(); 

    OrderDetail orderDetail = new OrderDetail(); 
    orderDetail.setOrder(order); 
    orderDetail.setItem(item); 
    orderDetail.setLineType("NLI"); 
    orderDetail.setPromItemNo("99999"); 

    List<OrderDetail> orderDeialsList = new ArrayList<>(); 
    orderDeialsList.add(orderDetail); 

    order.setOrderDetailsList(orderDeialsList);  

    ordersFacade.create(order); 

    Orders createdOrder = ordersFacade.find(order.getOrderNo()); 
    assertEquals(order, createdOrder); 
} 
+1

この[投稿](https://stackoverflow.com/questions/3585034/how-to-map-a-composite-key-with-hibernate/)は、どのように動作するかを理解するのに役立ちます。 –

+0

[テストケース](http://in.relation.to/2016/01/14/hibernate-jpa-test-case-template/)でレプリケートできれば、Jiraの問題を開く必要があります。 –

答えて

0

それはバグかもしれないが、いくつかの奇妙なマッピングの選択肢もここにもあります。

@JoinColumnは、挿入または更新時にFKを設定できないのはなぜですか?この場合、誰がFKを設定すべきですか?

@JoinColumn( 
    name = "ITEMNO", 
    referencedColumnName = "ITEMNO", 
    insertable = false, updatable = false 
) 

あなたはtest caseでそれを複製することができます場合は、JIRA課題を開く必要があります。

+0

これは、このFKがコンポジットPKの一部であり、@ ID –

+0

でアノテーションされているためです。また、私は、テスト関数ロジックをOrderFacade EJBに移動して、この関数を私のarquillianテストクラス通常は !!! –

関連する問題