1

Orderペアのように、子の所有エンティティのように機能する親の標準機能を実装したいと思いOrderLineます。1 つのビューで注文と注文明細を変更し、バージョン フィールド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 で上記のバージョン管理の問題を解決する一般的な方法はありますか?

4

0 に答える 0