Hibernate更新一到多级联 [英] Hibernate updating one to many cascaded

查看:99
本文介绍了Hibernate更新一到多级联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个实体,它们之间有一对多的关系。


购买---------- ------< lineCommand



我已将这些实体映射到一起,并且至少在我想要保存或删除购买时一切正常当我执行更新时,只有父母(购买将会更新),并且孩子不会更新。



这里的Purchase和lineCommand的DDL:
LineCommand:

  CREATE TABLE purchaseproduct 

idpurchaseproduct serial NOT NULL,
idpurchase integer ,
idproduct整数,
数量双精度,
价格双精度,
CONSTRAINT purchaseproduct_pkey PRIMARY KEY(idpurchaseproduct),
CONSTRAINT purchaseproduct_idproduct_fkey FOREIGN KEY(idproduct)
参考产品(idproduct)MATCH SIMPLE
ON UPDATE NO ACTION ON ACTION,
CONSTRAINT purchaseproduct_idpurchase_fkey FOREIGN KEY(idpurchase)
REFERENCES购买(idpurchase)MATCH SIMPLE
ON UPDATE NO采取行动删除没有活动ON

购买:

  CREATE TABLE购买

idpurchase serial NOT NULL,
code character varying(50),
不带时区的日期时间戳
totalht双精度,
tva双精度,
totalttc双精度,
CONSTRAINT purchase_pkey PRIMARY KEY(id购买)

POJOS:
LineCommand

  @Entity 
@Table(name =purchaseProduct)
@Access(AccessType.PROPERTY)
public class LineCommand实现Serializable {


private LongProperty idPurchaseProduct;
私人产品产品;
私人购买购买;
private DoubleProperty sellPrice = new SimpleDoubleProperty();
private DoubleProperty qty = new SimpleDoubleProperty();
private DoubleProperty subTotal = new SimpleDoubleProperty();


public LineCommand(){
this.idPurchaseProduct = new SimpleLongProperty();
this.product = new Product();
this.purchase = new Purchase();

this.sellPrice = new SimpleDoubleProperty();
this.qty = new SimpleDoubleProperty();
this.subTotal = new SimpleDoubleProperty();

NumberBinding subTotalBinding = Bindings.multiply(this.qty,this.sellPrice);
subTotal.bind(subTotalBinding);


$ b @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =purchase_seq_gen)
@SequenceGenerator(name =purchase_seq_gen ,sequenceName =purchaseproduct_idpurchaseproduct_seq,initialValue = 1,allocationSize = 1)
@Column(name =idpurchaseproduct,unique = true,nullable = false)
public long getIdPurchaseProduct(){
return idPurchaseProduct.get();
}

public LongProperty idPurchaseProductProperty(){
return idPurchaseProduct;
}

public void setIdPurchaseProduct(long idPurchaseProduct){
this.idPurchaseProduct.set(idPurchaseProduct);

$ b @ManyToOne
@JoinColumn(name =idproduct)
public Product getProduct(){
return product;
}

public void setProduct(Product product){
this.product = product;
}

@ManyToOne
@JoinColumn(name =idpurchase)
public购买getPurchase(){
return purchase;
}

public void setPurchase(购买购买){
this.purchase =购买;


$ b @Column(name =price)
public double getSellPrice(){
return sellPrice.get();
}

public DoubleProperty sellPriceProperty(){
return sellPrice;
}

public void setSellPrice(double sellPrice){
this.sellPrice.set(sellPrice);


@Column(name =qty)
public double getQty(){
return qty.get();
}

public DoubleProperty qtyProperty(){
return qty;
}

public void setQty(double qty){
this.qty.set(qty);
}

@Transient
public double getSubTotal(){
return subTotal.get();
}

public DoubleProperty subTotalProperty(){
return subTotal;
}

public void setSubTotal(double subTotal){
this.subTotal.set(subTotal);

$ b @Override
public boolean equals(Object obj){
if(obj == null){
return false;
} else {
Product product =((LineCommand)obj).getProduct();
购买购买=((LineCommand)obj).getPurchase();

if(this.product.equals(product)&&& this.purchase.equals(purchase))
return true;
else
返回false;



$ / code $ / pre
$ b

购买:

  @Entity 
@Table(name =purchase)
@Access(AccessType.PROPERTY)
公共类购买{
私有LongProperty idPurchase;
private StringProperty codePurchase;
private ObjectProperty< LocalDate> datePurchase;
私人DoubleProperty totalHt;
私人DoubleProperty tva;
私人DoubleProperty totalTTC;

私人设定< LineCommand> lineItems = new HashSet< LineCommand>(0);

public购买(){
this.idPurchase = new SimpleLongProperty();
this.codePurchase = new SimpleStringProperty();
this.datePurchase = new SimpleObjectProperty<>();
this.totalHt = new SimpleDoubleProperty();
this.tva = new SimpleDoubleProperty();
this.totalTTC = new SimpleDoubleProperty();



$ b @Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =purchase_seq_gen)
@SequenceGenerator(name =purchase_seq_gen,sequenceName =purchase_idpurchase_seq,initialValue = 1,allocationSize = 1)
@Column(name =idpurchase,unique = true,nullable = false)
public long getIdPurchase(){
return idPurchase.get();
}

public LongProperty idPurchaseProperty(){
return idPurchase;
}

public void setIdPurchase(long idPurchase){
this.idPurchase.set(idPurchase);

$ b $ @Column(name =code)
public String getCodePurchase(){
return codePurchase.get();
}

public StringProperty codePurchaseProperty(){
return codePurchase;
}

public void setCodePurchase(String codePurchase){
this.codePurchase.set(codePurchase);


@Column(name =date)
@Convert(converter = LocalDatePersistanceConverter.class)
public LocalDate getDatePurchase(){
return datePurchase.get();
}

public ObjectProperty< LocalDate> datePurchaseProperty(){
return datePurchase;
}

public void setDatePurchase(LocalDate datePurchase){
this.datePurchase.set(datePurchase);


@Column(name =totalHt)
public double getTotalHt(){
return totalHt.get();
}

public DoubleProperty totalHtProperty(){
return totalHt;
}

public void setTotalHt(double totalHt){
this.totalHt.set(totalHt);


@Column(name =tva)
public double getTva(){
return tva.get();
}

public DoubleProperty tvaProperty(){
return tva;
}

public void setTva(double tva){
this.tva.set(tva);


@Column(name =totalTTC)
public double getTotalTTC(){
return totalTTC.get();
}

public DoubleProperty totalTTCProperty(){
return totalTTC;
}

public void setTotalTTC(double totalTTC){
this.totalTTC.set(totalTTC);



@OneToMany(mappedBy =purchase,cascade = CascadeType.ALL,fetch = FetchType.EAGER)
public Set< LineCommand> getLineItems(){
return this.lineItems;
}

public void setLineItems(Set< LineCommand> lineItems){
this.lineItems = lineItems;

$ b @Override
public boolean equals(Object obj){
if(obj == null){
return false;
} else {

if(this.idPurchase.getValue()==((Purchase)obj).getIdPurchase())
return true;
else
返回false;
}
}

}

她我通过DAO执行一些更新:

$ p $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ {
if(!session.isOpen())
session = DatabaseUtil.getSessionFactory()。openSession();
session.beginTransaction();

Purchase purchase = session.get(Purchase.class,obj.getIdPurchase());
purchase.setCodePurchase(obj.getCodePurchase());
purchase.setDatePurchase(obj.getDatePurchase());
purchase.setTotalHt(obj.getTotalHt());
purchase.setTva(obj.getTva());
purchase.setTotalTTC(obj.getTotalTTC());
//purchase.getLineItems()。clear();
//这里我设置行项目
// purchase.setLineItems(obj.getLineItems());


session.getTransaction()。commit();
session.close();
返回true;

} catch(Exception e){
e.printStackTrace();
返回false;
}

}

注意:只有父母会更新,所以更新不会级联。

解决方案

obj.getLineItems()返回一组分离的实例(它们与当前的Hibernate会话没有关联)。解决该问题的最简单方法是在提交交易之前合并 Purchase >:

  purchase = session.merge(purchase); 

这种合并操作将级联到相关的 LineCommand 实例。


I have two entities, which have one to many relationships.

Purchase ----------------< lineCommand

I have mapped those entities together, and everything works fine at least when I want to save or delete a purchase, except when I perform an update, only the parent (purchase will be update) and children won't be updated.

Here the DDL for both Purchase and lineCommand: LineCommand:

CREATE TABLE purchaseproduct
(
  idpurchaseproduct serial NOT NULL,
  idpurchase integer,
  idproduct integer,
  qty double precision,
  price double precision,
  CONSTRAINT purchaseproduct_pkey PRIMARY KEY (idpurchaseproduct),
  CONSTRAINT purchaseproduct_idproduct_fkey FOREIGN KEY (idproduct)
      REFERENCES product (idproduct) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT purchaseproduct_idpurchase_fkey FOREIGN KEY (idpurchase)
      REFERENCES purchase (idpurchase) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

Purchase:

 CREATE TABLE purchase
    (
      idpurchase serial NOT NULL,
      code character varying(50),
      date timestamp without time zone,
      totalht double precision,
      tva double precision,
      totalttc double precision,
      CONSTRAINT purchase_pkey PRIMARY KEY (idpurchase)
    )

The POJOS: LineCommand

 @Entity
    @Table(name = "purchaseProduct")
    @Access(AccessType.PROPERTY)
    public class LineCommand implements Serializable {


        private LongProperty idPurchaseProduct;
        private Product product;
        private Purchase purchase;
        private DoubleProperty sellPrice = new SimpleDoubleProperty();
        private DoubleProperty qty = new SimpleDoubleProperty();
        private DoubleProperty subTotal = new SimpleDoubleProperty();


        public LineCommand() {
            this.idPurchaseProduct = new SimpleLongProperty();
            this.product = new Product();
            this.purchase = new Purchase();

            this.sellPrice = new SimpleDoubleProperty();
            this.qty = new SimpleDoubleProperty();
            this.subTotal = new SimpleDoubleProperty();

            NumberBinding subTotalBinding = Bindings.multiply(this.qty, this.sellPrice);
            subTotal.bind(subTotalBinding);

        }

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purchase_seq_gen")
        @SequenceGenerator(name = "purchase_seq_gen", sequenceName = "purchaseproduct_idpurchaseproduct_seq", initialValue = 1, allocationSize = 1)
        @Column(name = "idpurchaseproduct ", unique = true, nullable = false)
        public long getIdPurchaseProduct() {
            return idPurchaseProduct.get();
        }

        public LongProperty idPurchaseProductProperty() {
            return idPurchaseProduct;
        }

        public void setIdPurchaseProduct(long idPurchaseProduct) {
            this.idPurchaseProduct.set(idPurchaseProduct);
        }

        @ManyToOne
        @JoinColumn(name = "idproduct")
        public Product getProduct() {
            return product;
        }

        public void setProduct(Product product) {
            this.product = product;
        }

        @ManyToOne
        @JoinColumn(name = "idpurchase")
        public Purchase getPurchase() {
            return purchase;
        }

        public void setPurchase(Purchase purchase) {
            this.purchase = purchase;
        }


        @Column(name = "price")
        public double getSellPrice() {
            return sellPrice.get();
        }

        public DoubleProperty sellPriceProperty() {
            return sellPrice;
        }

        public void setSellPrice(double sellPrice) {
            this.sellPrice.set(sellPrice);
        }

        @Column(name = "qty")
        public double getQty() {
            return qty.get();
        }

        public DoubleProperty qtyProperty() {
            return qty;
        }

        public void setQty(double qty) {
            this.qty.set(qty);
        }

        @Transient
        public double getSubTotal() {
            return subTotal.get();
        }

        public DoubleProperty subTotalProperty() {
            return subTotal;
        }

        public void setSubTotal(double subTotal) {
            this.subTotal.set(subTotal);
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            } else {
                Product product = ((LineCommand) obj).getProduct();
                Purchase purchase = ((LineCommand) obj).getPurchase();

                if (this.product.equals(product) && this.purchase.equals(purchase))
                    return true;
                else
                    return false;
            }
        }
    }

Purchase:

@Entity
@Table(name = "purchase")
@Access(AccessType.PROPERTY)
public class Purchase {
    private LongProperty idPurchase;
    private StringProperty codePurchase;
    private ObjectProperty<LocalDate> datePurchase;
    private DoubleProperty totalHt;
    private DoubleProperty tva;
    private DoubleProperty totalTTC;

    private Set<LineCommand> lineItems = new HashSet<LineCommand>(0);

    public Purchase() {
        this.idPurchase = new SimpleLongProperty();
        this.codePurchase = new SimpleStringProperty();
        this.datePurchase = new SimpleObjectProperty<>();
        this.totalHt = new SimpleDoubleProperty();
        this.tva = new SimpleDoubleProperty();
        this.totalTTC = new SimpleDoubleProperty();


    }

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purchase_seq_gen")
    @SequenceGenerator(name = "purchase_seq_gen", sequenceName = "purchase_idpurchase_seq", initialValue = 1, allocationSize = 1)
    @Column(name = "idpurchase", unique = true, nullable = false)
    public long getIdPurchase() {
        return idPurchase.get();
    }

    public LongProperty idPurchaseProperty() {
        return idPurchase;
    }

    public void setIdPurchase(long idPurchase) {
        this.idPurchase.set(idPurchase);
    }

    @Column(name = "code")
    public String getCodePurchase() {
        return codePurchase.get();
    }

    public StringProperty codePurchaseProperty() {
        return codePurchase;
    }

    public void setCodePurchase(String codePurchase) {
        this.codePurchase.set(codePurchase);
    }

    @Column(name = "date")
    @Convert(converter = LocalDatePersistanceConverter.class)
    public LocalDate getDatePurchase() {
        return datePurchase.get();
    }

    public ObjectProperty<LocalDate> datePurchaseProperty() {
        return datePurchase;
    }

    public void setDatePurchase(LocalDate datePurchase) {
        this.datePurchase.set(datePurchase);
    }

    @Column(name = "totalHt")
    public double getTotalHt() {
        return totalHt.get();
    }

    public DoubleProperty totalHtProperty() {
        return totalHt;
    }

    public void setTotalHt(double totalHt) {
        this.totalHt.set(totalHt);
    }

    @Column(name = "tva")
    public double getTva() {
        return tva.get();
    }

    public DoubleProperty tvaProperty() {
        return tva;
    }

    public void setTva(double tva) {
        this.tva.set(tva);
    }

    @Column(name = "totalTTC")
    public double getTotalTTC() {
        return totalTTC.get();
    }

    public DoubleProperty totalTTCProperty() {
        return totalTTC;
    }

    public void setTotalTTC(double totalTTC) {
        this.totalTTC.set(totalTTC);
    }


    @OneToMany(mappedBy = "purchase", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    public Set<LineCommand> getLineItems() {
        return this.lineItems;
    }

    public void setLineItems(Set<LineCommand> lineItems) {
        this.lineItems = lineItems;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        } else {

            if (this.idPurchase.getValue() == ((Purchase) obj).getIdPurchase())
                return true;
            else
                return false;
        }
    }

}

And her where i performe some updates via DAO :

    Purchase
    public boolean update(Purchase obj) {
        try {
            if (!session.isOpen())
                session = DatabaseUtil.getSessionFactory().openSession();
            session.beginTransaction();

            Purchase purchase = session.get(Purchase.class, obj.getIdPurchase());
            purchase.setCodePurchase(obj.getCodePurchase());
            purchase.setDatePurchase(obj.getDatePurchase());
            purchase.setTotalHt(obj.getTotalHt());
            purchase.setTva(obj.getTva());
            purchase.setTotalTTC(obj.getTotalTTC());
            //purchase.getLineItems().clear();
            // Here where i set line items
            // purchase.setLineItems(obj.getLineItems());


            session.getTransaction().commit();
            session.close();
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

Notice: Only the parent will update, so the update is not cascaded.

解决方案

obj.getLineItems() returns a set of detached instances (they are not associated with the current Hibernate session). The easiest way to resolve the issue is to merge the Purchase before committing the transaction:

purchase = session.merge(purchase);

This way merge operation will be cascaded to the associated LineCommand instances.

这篇关于Hibernate更新一到多级联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆