前些天在做项目的时候需要用到Hibernate的级联保存和更新,出现了几个错误,已经解决了这里记上一笔。
首先是实例:
@Entity @Table(name = "tbl_order") public class Order { @Id @GeneratedValue(generator = "ORDER_ID") @GenericGenerator(strategy = "assigned", name = "ORDER_ID") private Integer id; @OneToOne @JoinColumn(name = "orderId") private OperationTime operationTimes; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public OperationTime getOperationTimes() { return operationTimes; } public void setOperationTimes(OperationTime operationTimes) { this.operationTimes = operationTimes; } } @Entity @Table(name = "tbl_order_extension") public class OperationTime { @Id @GeneratedValue(generator = "ORDER_ID") @GenericGenerator(strategy = "assigned", name = "ORDER_ID") private Integer orderId; @Column(name = "apply_time") private Date applyTime; @Column(name = "accept_time") private Date acceptTime; @OneToOne @JoinColumn(name = "id") private Order order; public Integer getOrderId() { return orderId; } public void setOrderId(Integer orderId) { this.orderId = orderId; } public Date getApplyTime() { return applyTime; } public void setApplyTime(Date applyTime) { this.applyTime = applyTime; } public Date getAcceptTime() { return acceptTime; } public void setAcceptTime(Date acceptTime) { this.acceptTime = acceptTime; } public Order getOrder() { return order; } public void setOrder(Order order) { this.order = order; } }
Order和OperationTime是一对一的映射关系,在级联保存的时候需要这样写:
public void saveOrder(Order order){ //business code OperationTime operationTimes = new OperationTime(); operationTimes.setApplyTime(new Date()); operationTimes.setOrder(order); //operationTimes.setOrderId(order.getId()); a order.setOperationTimes(operationTimes); orderDao.save(order); }
千万不能像a处给operationTimes.orderId赋值,因为如果在这里能取到值Hibernate会默认执行update语句这样就会出现错误。
Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
但是不赋值我的副类主键是需要分配的,且是主键关联,需要将其主键生成策略做下修改。
@Id @GeneratedValue(generator = "foreign") @GenericGenerator(name = "foreign", strategy = "foreign", parameters = { @Parameter(name = "property", value = "order") }) private Integer orderId;
同理在更新的时候一定别忘了为operationTimes.orderId赋值,否则将会执行create语句。因为我这里是分配的主键策略是assigned的会报ids must be manually assigned