我想实现父母的标准功能,就像它的孩子的拥有实体一样,就像对Order
- OrderLine
。我想在一个视图中修改订单和订单行,并仅提供基于版本字段的乐观锁定Order
。我还想将索引列表用作索引存储在数据库中的集合。
我尝试了不同的设置,但都没有奏效。我的设置是:
数据库脚本:
CREATE TABLE Site_Order (
order_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
order_number INT NOT NULL,
version BIGINT NOT NULL
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO Site_Order (order_number, version) VALUES (1, 1);
CREATE TABLE Order_Line (
order_line_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
order_id INT NOT NULL,
product_name VARCHAR(100),
idx INT NOT NULL,
FOREIGN KEY (order_id) REFERENCES Site_Order(order_id) ON UPDATE CASCADE ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO Order_Line (order_id, product_name, idx) VALUES (1, "Coffee", 0);
实体:
@Entity @Table(name = "site_order")
public class SiteOrder implements java.io.Serializable {
private Integer orderId;
private int orderNumber;
private long version;
private List<OrderLine> orderLines = new ArrayList<OrderLine>(0);
//constructors, fileds getters and setters
@OneToMany(fetch = FetchType.LAZY, orphanRemoval=true)
@Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE, CascadeType.MERGE})
@OrderColumn(name="idx", nullable=false)
@JoinColumn(name="order_id", nullable=false)
public List<OrderLine> getOrderLines() {
return this.orderLines;
}
protected void setOrderLines(List<OrderLine> orderLines) {
this.orderLines = orderLines;
}
public void addOrderLine(OrderLine ol) {
orderLines.add(ol);
if (!orderLine.getSiteOrder().equals(this)) {
orderLine.getSiteOrder().getOrderLines().remove(orderLine);
orderLine.setSiteOrder(this);
}
}
public void removeOrderLine(OrderLine ol) {
orderLines.remove(ol);
if (orderLine.getSiteOrder().equals(this)) {
orderLine.setSiteOrder(null);
}
}
}
@Entity @Table(name = "order_line")
public class OrderLine implements java.io.Serializable {
private Integer orderLineId;
private SiteOrder siteOrder;
private String productName;
//constructors, fileds getters and setters
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", nullable = false, insertable=false, updatable=false)
public SiteOrder getSiteOrder() {
return this.siteOrder;
}
public void setSiteOrder(SiteOrder siteOrder) {
this.siteOrder = siteOrder;
if ((siteOrder != null) && (!siteOrder.getOrderLines().contains(this))) {
siteOrder.addOrderLine(this);
}
}
}
典型用法是 (1) 向现有订单添加新订单行,其中订单版本得到更新; (2) 修改订单行的属性,如数量、产品、价格等,不影响订单版本。
(1):
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
SiteOrder s = (SiteOrder)session.get(SiteOrder.class, Integer.valueOf(1));
OrderLine o = new OrderLine();
o.setProductName("Cup");
s.addOrderLine(o);
session.getTransaction().commit();
session.close();
(2):
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
SiteOrder s = (SiteOrder)session.get(SiteOrder.class, Integer.valueOf(1));
s.getOrderLines().get(0).setProductName("Tea");
session.getTransaction().commit();
session.close();
有没有办法在 Hibernate 中实现上述版本控制问题的通用解决方案?