我正在开发一个 Hibernate + Spring + MYSQL 项目。我在尝试更新子表时遇到问题(外键表) 我可以插入和删除条目,但无法更新。我尝试过很多东西,但没有什么对我有用。
对PurchaseOrder的CRUD操作,即父表工作正常。
我已经从hibernate revenge文件xml创建了实体。
PurchaseOrder
与PurchaseOrderDetail
一对多关系。
我的实体是,
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();
}
}
答案 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
行的整个生命周期内更改prodUnitRate
和TpurchaseOrderDetail
,而原始代码则不会这样做。