Hibernate:Session.update()不起作用

时间:2015-12-17 15:44:18

标签: java mysql hibernate

我正在开发一个 Hibernate + Spring + MYSQL 项目。我在尝试更新子表时遇到问题(外键表) 我可以插入和删除条目,但无法更新。我尝试过很多东西,但没有什么对我有用。

对PurchaseOrder的CRUD操作,即父表工作正常。

我已经从hibernate revenge文件xml创建了实体。

Table Relation:

PurchaseOrderPurchaseOrderDetail 一对多关系。

我的实体是,

TpurchaseOrder.java

@Entity
@Table(name = "tpurchase_order", catalog = "peonydb")
public class TpurchaseOrder implements java.io.Serializable {

private long purchaseId;
private long VId;
private float purchaseAmount;
private Date paymentDueDate;
private float vat;
private boolean purchaseApproval;
private Set<TpurchaseOrderDetail> tpurchaseOrderDetails = new HashSet<TpurchaseOrderDetail>(0);

public TpurchaseOrder() {
}

public TpurchaseOrder(long purchaseId, long VId, float purchaseAmount, Date paymentDueDate, float vat,
        boolean purchaseApproval) {
    this.purchaseId = purchaseId;
    this.VId = VId;
    this.purchaseAmount = purchaseAmount;
    this.paymentDueDate = paymentDueDate;
    this.vat = vat;
    this.purchaseApproval = purchaseApproval;
}

public TpurchaseOrder(long purchaseId, long VId, float purchaseAmount, Date paymentDueDate, float vat,
        boolean purchaseApproval, Set<TpurchaseOrderDetail> tpurchaseOrderDetails) {
    this.purchaseId = purchaseId;
    this.VId = VId;
    this.purchaseAmount = purchaseAmount;
    this.paymentDueDate = paymentDueDate;
    this.vat = vat;
    this.purchaseApproval = purchaseApproval;
    this.tpurchaseOrderDetails = tpurchaseOrderDetails;
}

@Id

@Column(name = "PURCHASE_ID", unique = true, nullable = false)
public long getPurchaseId() {
    return this.purchaseId;
}

public void setPurchaseId(long purchaseId) {
    this.purchaseId = purchaseId;
}

@Column(name = "V_ID", nullable = false)
public long getVId() {
    return this.VId;
}

public void setVId(long VId) {
    this.VId = VId;
}

@Column(name = "PURCHASE_AMOUNT", nullable = false, precision = 12, scale = 0)
public float getPurchaseAmount() {
    return this.purchaseAmount;
}

public void setPurchaseAmount(float purchaseAmount) {
    this.purchaseAmount = purchaseAmount;
}

@Temporal(TemporalType.DATE)
@Column(name = "PAYMENT_DUE_DATE", nullable = false, length = 0)
public Date getPaymentDueDate() {
    return this.paymentDueDate;
}

public void setPaymentDueDate(Date paymentDueDate) {
    this.paymentDueDate = paymentDueDate;
}

@Column(name = "VAT", nullable = false, precision = 12, scale = 0)
public float getVat() {
    return this.vat;
}

public void setVat(float vat) {
    this.vat = vat;
}

@Column(name = "PURCHASE_APPROVAL", nullable = false)
public boolean isPurchaseApproval() {
    return this.purchaseApproval;
}

public void setPurchaseApproval(boolean purchaseApproval) {
    this.purchaseApproval = purchaseApproval;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "tpurchaseOrder")
public Set<TpurchaseOrderDetail> getTpurchaseOrderDetails() {
    return this.tpurchaseOrderDetails;
}

public void setTpurchaseOrderDetails(Set<TpurchaseOrderDetail> tpurchaseOrderDetails) {
    this.tpurchaseOrderDetails = tpurchaseOrderDetails;
}

}

TpurchaseOrderDetail.java

@Entity
@Table(name = "tpurchase_order_detail", catalog = "peonydb",     uniqueConstraints = @UniqueConstraint(columnNames = {
    "PURCHASE_ID", "PROD_ID" }) )
public class TpurchaseOrderDetail implements java.io.Serializable {

private TpurchaseOrderDetailId id;
private TpurchaseOrder tpurchaseOrder;

public TpurchaseOrderDetail() {
}

public TpurchaseOrderDetail(TpurchaseOrderDetailId id, TpurchaseOrder tpurchaseOrder) {
    this.id = id;
    this.tpurchaseOrder = tpurchaseOrder;
}

@EmbeddedId

@AttributeOverrides({
        @AttributeOverride(name = "purchaseId", column = @Column(name = "PURCHASE_ID", nullable = false) ),
        @AttributeOverride(name = "prodId", column = @Column(name = "PROD_ID", nullable = false) ),
        @AttributeOverride(name = "prodQuantity", column = @Column(name = "PROD_QUANTITY", nullable = false) ),
        @AttributeOverride(name = "prodUnitRate", column = @Column(name = "PROD_UNIT_RATE", nullable = false, precision = 12, scale = 0) ) })
public TpurchaseOrderDetailId getId() {
    return this.id;
}

public void setId(TpurchaseOrderDetailId id) {
    this.id = id;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "PURCHASE_ID", nullable = false, insertable = false, updatable = false)
public TpurchaseOrder getTpurchaseOrder() {
    return this.tpurchaseOrder;
}

public void setTpurchaseOrder(TpurchaseOrder tpurchaseOrder) {
    this.tpurchaseOrder = tpurchaseOrder;
}

}

TpurchaseOrderDetailId.java

@Embeddable
public class TpurchaseOrderDetailId implements java.io.Serializable {

private long purchaseId;
private long prodId;
private long prodQuantity;
private float prodUnitRate;

public TpurchaseOrderDetailId() {
}

public TpurchaseOrderDetailId(long purchaseId, long prodId, long prodQuantity, float prodUnitRate) {
    this.purchaseId = purchaseId;
    this.prodId = prodId;
    this.prodQuantity = prodQuantity;
    this.prodUnitRate = prodUnitRate;
}

@Column(name = "PURCHASE_ID", nullable = false)
public long getPurchaseId() {
    return this.purchaseId;
}

public void setPurchaseId(long purchaseId) {
    this.purchaseId = purchaseId;
}

@Column(name = "PROD_ID", nullable = false)
public long getProdId() {
    return this.prodId;
}

public void setProdId(long prodId) {
    this.prodId = prodId;
}

@Column(name = "PROD_QUANTITY", nullable = false)
public long getProdQuantity() {
    return this.prodQuantity;
}

public void setProdQuantity(long prodQuantity) {
    this.prodQuantity = prodQuantity;
}

@Column(name = "PROD_UNIT_RATE", nullable = false, precision = 12, scale = 0)
public float getProdUnitRate() {
    return this.prodUnitRate;
}

public void setProdUnitRate(float prodUnitRate) {
    this.prodUnitRate = prodUnitRate;
}

public boolean equals(Object other) {
    if ((this == other))
        return true;
    if ((other == null))
        return false;
    if (!(other instanceof TpurchaseOrderDetailId))
        return false;
    TpurchaseOrderDetailId castOther = (TpurchaseOrderDetailId) other;

    return (this.getPurchaseId() == castOther.getPurchaseId()) && (this.getProdId() == castOther.getProdId())
            && (this.getProdQuantity() == castOther.getProdQuantity())
            && (this.getProdUnitRate() == castOther.getProdUnitRate());
}

public int hashCode() {
    int result = 17;

    result = 37 * result + (int) this.getPurchaseId();
    result = 37 * result + (int) this.getProdId();
    result = 37 * result + (int) this.getProdQuantity();
    result = 37 * result + (int) this.getProdUnitRate();
    return result;
}

}

更新代码方法:

@Transactional
@Override
public String updatePO(PurchaseOrderPojo purchaseOrderPojo,
        ArrayList<PurchaseOrderDetailIdPojo> updatedPurchasedProductsList, String purchaseId) {
    final Transaction transaction;
    try {
        if (this.session != null && !this.session.isConnected()) {
            this.session = this.sessionFactory.openSession();
        } else {
            this.session = this.sessionFactory.getCurrentSession();
        }
        transaction = session.beginTransaction();

        TpurchaseOrder tpurchaseOrder = (TpurchaseOrder) session.get(TpurchaseOrder.class,
                Long.parseLong(purchaseId));

        List<TpurchaseOrderDetail> tpurchaseOrderDetailListFromDB = null;
        if (purchaseOrderPojo != null) {
            tpurchaseOrder.setVId(purchaseOrderPojo.getVId());
            tpurchaseOrder.setVat(purchaseOrderPojo.getVat());
            // to be set later on once the PO is approved
            tpurchaseOrder.setPurchaseApproval(false);
            tpurchaseOrder.setPaymentDueDate(DateUtils.StringtoUtilDate(purchaseOrderPojo.getPaymentDueDate()));
            tpurchaseOrder.setPurchaseAmount(getPurchaseAmount(purchaseOrderPojo, updatedPurchasedProductsList));
            session.update(tpurchaseOrder); // THIS WORKS FINE I CAN SEE UPDATE QUERY ON CONSOLE FOR THIS PARENT TABLE

            Criteria criteria = session.createCriteria(TpurchaseOrderDetail.class);
            criteria.add(Restrictions.eq("id.purchaseId", Long.parseLong(purchaseId)));
            tpurchaseOrderDetailListFromDB = criteria.list();

            for (PurchaseOrderDetailIdPojo purchaseOrderDetailIdUpdatedObj : updatedPurchasedProductsList) {
                isObjectPresent = false;
                for (TpurchaseOrderDetail tpurchaseOrderDetailObjFromDB : tpurchaseOrderDetailListFromDB) {
                    // if the purchase product is already present in the DB
                    // then update it

                    if (tpurchaseOrderDetailObjFromDB.getId().getProdId() == purchaseOrderDetailIdUpdatedObj
                            .getProdId()) {
                        TpurchaseOrderDetailId tpurchaseOrderDetailId = tpurchaseOrderDetailObjFromDB.getId();
                        tpurchaseOrderDetailId.setProdQuantity(purchaseOrderDetailIdUpdatedObj.getProdQuantity());                          
                        tpurchaseOrderDetailId.setProdUnitRate(purchaseOrderDetailIdUpdatedObj.getProdUnitRate());
                        tpurchaseOrderDetailObjFromDB.setId(tpurchaseOrderDetailId);

                        session.update(tpurchaseOrderDetailObjFromDB); // THIS IS NOT WORKING, I EVEN TRIED USING saveOrUpdate METHOD
                        session.flush();                            
                    }                       
                }
            }
        }
        transaction.commit();
        return StringConstants.SUCCESS_STR;
    } catch (Exception exception) {
        // rollback procedure to be implemented
        exception.printStackTrace();
        return exception.getMessage();
    }
}

1 个答案:

答案 0 :(得分:0)

更新失败的原因是您尝试更改记录的主键,这在关系数据库中是不允许的。

我会建议以下内容(为简洁起见,删除了注释/ getter / setter)。

<强> TpurchaseOrderDetailId.java

public class TpurchaseOrderDetailId {
  private long purchaseId;
  private long prodId;
}

<强> TpurchaseOrderDetail.java

public class TpurchaseOrderDetail {
  private TpurchaseOrderDetailId id;
  private TpurchaseOrder tpurchaseOrder;
  private long prodQuantity;
  private float prodUnitRate;
}

这将允许在prodQuantity行的整个生命周期内更改prodUnitRateTpurchaseOrderDetail,而原始代码则不会这样做。