在不同的会话中使用相同的外键保存休眠对象时出现错误。 下面是休眠类:
OrderInfo.java
@Entity
@Table(name = "ORDER_INFO", uniqueConstraints = {
@UniqueConstraint(columnNames = {"ORDER_ID", "CREATION_TIMESTAMP"})
})
public class OrderInfo implements Serializable {
@Id
@Column(name = "ORDER_PK")
@GeneratedValue(strategy = GenerationType.AUTO)
private Long OrderPK;
@Column(name = "ORDER_ID", nullable = false)
private String OrderId;
@Column(name = "CREATION_TIMESTAMP", nullable = false)
private String creationTimestamp;
@Column(name = "USER", nullable = false)
private String user;
}
OrderLeg.java
@Entity
@Table(name = "ORDER_LEG")
@IdClass(OrderLegKey.class)
public class OrderLeg implements Serializable {
@Id
private Integer legIndex;
@Id
@ManyToOne
@JoinColumn(name = "ORDER_FK", referencedColumnName = "ORDER_PK")
private OrderInfo OrderFK;
@Column(name = "LEG_DESC")
private String legDesc;
//Constructor
public OrderLeg(Integer legIndex, OrderInfo OrderFK) {
this.legIndex = legIndex;
this.orderFK = OrderFK;
}
}
OrderLegKey.java
public class OrderLegKey implements Serializable {
private Integer legIndex;
private Long OrderFK;
public Integer getLegIndex() {
return legIndex;
}
public void setLegIndex(Integer legIndex) {
this.legIndex = legIndex;
}
public Long getOrderFK() {
return OrderFK;
}
public void setOrderFK(Long OrderFK) {
this.OrderFK = OrderFK;
}
}
OrderInfo
表包含有关可以包含多个orderLeg的订单的信息。OrderLeg
表具有引用到OrderPK
表的OrderInfo
列的外键。要求是可以在不同的会话中将OrderLegs添加到OrderInfo。第一次在同一会话中成功保存成功,但是下次在不同会话中成功保存OrderLegs到已经保存的OrderInfo记录中。下面是保存对象的代码:
public static void main(String[] args) {
//Below is SUCCESS
Session session = HibernateUtils.getSession();
OrderInfo OrderInfo = new OrderInfo();
OrderInfo.setOrderId("o2");
OrderInfo.setCreationTimestamp("t1");
OrderInfo.setUser("dan");
OrderLeg leg1 = new OrderLeg(1, OrderInfo);
OrderLeg leg2 = new OrderLeg(2, OrderInfo);
try {
session.beginTransaction();
session.save(OrderInfo);
session.save(leg1);
session.save(leg2);
session.getTransaction().commit();
} finally {
session.close();
}
//Below gets FAILED
session = HibernateUtils.getSession();
OrderLeg leg3 = new OrderLeg(3, OrderInfo);
OrderLeg leg4 = new OrderLeg(4, OrderInfo);
try {
session.beginTransaction();
session.save(OrderInfo);
session.save(leg3);
session.save(leg4);
session.getTransaction().commit();
} finally {
session.close();
}
}
在第二个会话中保存对象时,出现异常:
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:59)
.............................
.............................
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'o3-t1' for key 'UKoq9eddrx65xhf1gudrs0csrw2'
............................
问题是,当我尝试在第二个会话中保存Orderleg时,休眠模式首先运行OrderInfo的插入查询,该查询已保存在数据库中,这就是为什么ConstrainVoilation异常发生的原因。
OrderInfo
对象时,可以避免对OrderLeg
进行插入查询吗? (当我尝试保存Orderleg
对象时,Hibernate首先对OrderInfo运行插入查询,然后对OrderLeg
对象运行插入查询)欢迎提出任何建议。预先感谢。