Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将@IdClass与Hibernate和arquillian force级联类型一起使用。在作为实体复合主键一部分的多个单键外键对象上插入_Java_Hibernate_Jpa_Jpa 2.0 - Fatal编程技术网

Java 将@IdClass与Hibernate和arquillian force级联类型一起使用。在作为实体复合主键一部分的多个单键外键对象上插入

Java 将@IdClass与Hibernate和arquillian force级联类型一起使用。在作为实体复合主键一部分的多个单键外键对象上插入,java,hibernate,jpa,jpa-2.0,Java,Hibernate,Jpa,Jpa 2.0,我试图从我的arquillian测试类中持久化一个新的Order对象。 order实体包含OrderDetail实体的列表,该实体具有由4个字段组成的主键 但是,当Hibernate尝试插入新的OrderDetail对象时,它也会插入非新的项对象(项是OrderDetail实体中的主要PK字段之一,并用@ID注释),这会导致DB中的项表出现唯一的约束异常 注意,我从@OneToMany注释项中删除了CascadeType 还尝试了级联类型。刷新,但我得到了相同的结果,没有任何改变。它的工作原理是

我试图从我的arquillian测试类中持久化一个新的Order对象。 order实体包含OrderDetail实体的列表,该实体具有由4个字段组成的主键

但是,当Hibernate尝试插入新的OrderDetail对象时,它也会插入非新的项对象(项是OrderDetail实体中的主要PK字段之一,并用@ID注释),这会导致DB中的项表出现唯一的约束异常

注意,我从@OneToMany注释项中删除了CascadeType 还尝试了级联类型。刷新,但我得到了相同的结果,没有任何改变。它的工作原理是强制级联类型。在所有情况下插入

当我使用@EmbeddedId注释而不是@IDClass时,它的工作效果与预期一致 但是我想知道为什么它不能与@IDClass一起工作?它是冬眠中的虫子吗?它应该按照标准完美地工作

订单实体

@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
}
@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;
@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 + " ]";
}

}
项目实体

@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
}
@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;
@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);
}
@RunWith(Arquillian.class)
公共类ordersfacadest
{
@注入
订单facade本地订单facade;
@注入
ItemFacadeLocalItemFacade;
@试验
public void testCreateOrder()引发异常
{
ItemItem=itemFacade.find(“20247912”);
订单=新订单();
OrderDetail OrderDetail=新的OrderDetail();
orderDetail.setOrder(订单);
orderDetail.setItem(项目);
orderDetail.setLineType(“NLI”);
orderDetail.setPromItemNo(“99999”);
List OrderDeialList=新建ArrayList();
添加(orderDetail);
order.setOrderDetailsList(OrderDeialList);
ordersFacade.create(订单);
Orders createdOrder=ordersFacade.find(order.getOrderNo());
assertEquals(订单、createdOrder);
}

这可能是一个bug,但这里也有一些奇怪的映射选择

为什么不允许
@JoinColumn
在插入或更新时设置FK?在这种情况下,谁应该设置FK

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

如果你可以用a复制它,那么你应该打开一个Jira问题。

假设这可能有助于了解它是如何工作的。如果你可以用a复制它,那么你应该打开一个Jira问题。这是因为这个FK是复合PK的一部分,并用@IDAlso注释。因此,当我移动测试fu时,我发现了一些非常奇怪的事情nction逻辑到OrderFacade EJB,只需从my arquillian测试类调用此函数即可正常工作!!!