In Hibernate, you need to have special field in order to accomplish a composite primary key to make it as a single key object:
To handle composite primary key, you need to user an extra class “RmaLinePk”.
CREATE TABLE `rma_hdr` ( `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `rma_num` VARCHAR(20) NOT NULL DEFAULT '', `rma_hdr_sts_cd` VARCHAR(20) NULL DEFAULT NULL, `rtrn_tp_cd` VARCHAR(20) NOT NULL DEFAULT '', `rtrn_rsn_cd` VARCHAR(20) NULL DEFAULT NULL, `sell_to_cust_cd` VARCHAR(20) NULL DEFAULT NULL, PRIMARY KEY (`id`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB AUTO_INCREMENT=27 ;
CREATE TABLE `rma_line` ( `rma_num` VARCHAR(20) NOT NULL DEFAULT '', `rma_line_num` VARCHAR(20) NOT NULL DEFAULT '', `rma_line_sts_cd` VARCHAR(20) NOT NULL DEFAULT '', `mdse_cd` VARCHAR(20) NOT NULL DEFAULT '', `qty` INT(11) UNSIGNED NOT NULL DEFAULT '0', `rma_id` INT(11) UNSIGNED NOT NULL, PRIMARY KEY (`rma_num`, `rma_line_num`), INDEX `rma_id` (`rma_id`), CONSTRAINT `rma_line_ibfk_1` FOREIGN KEY (`rma_id`) REFERENCES `rma_hdr` (`id`) ON DELETE CASCADE ) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
package com.ns.spring.model; import java.util.List; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import com.ns.spring.model.ui.RmaHdrModel; /** * Entity bean with JPA annotations Hibernate provides JPA implementation */ @Entity @Table(name = "RMA_HDR") public class RMA_HDR { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; @Column(name = "rma_num") private String rmaNum; @Column(name = "rma_hdr_sts_cd") private String rmaHdrStsCd; @Column(name = "rtrn_tp_cd") private String rtrnTpCd; @Column(name = "rtrn_rsn_cd") private String rtrnRsnCd; @Column(name = "sell_to_cust_cd") private String sellToCustCd; @OneToMany(mappedBy = "rmaHdr", targetEntity = RMA_LINE.class, fetch = FetchType.EAGER, cascade = CascadeType.ALL) private List<RMA_LINE> rmaLines; public RMA_HDR(){} public RMA_HDR(RmaHdrModel hdr) { this.id = hdr.getId(); this.rmaNum = hdr.getRmaNum(); this.rmaHdrStsCd = hdr.getRmaHdrStsCd(); this.rtrnTpCd = hdr.getRtrnTpCd(); this.rtrnRsnCd = hdr.getRtrnRsnCd(); this.sellToCustCd = hdr.getSellToCustCd(); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getRmaNum() { return rmaNum; } public void setRmaNum(String rmaNum) { this.rmaNum = rmaNum; } public String getRmaHdrStsCd() { return rmaHdrStsCd; } public void setRmaHdrStsCd(String rmaHdrStsCd) { this.rmaHdrStsCd = rmaHdrStsCd; } public String getRtrnTpCd() { return rtrnTpCd; } public void setRtrnTpCd(String rtrnTpCd) { this.rtrnTpCd = rtrnTpCd; } public String getRtrnRsnCd() { return rtrnRsnCd; } public void setRtrnRsnCd(String rtrnRsnCd) { this.rtrnRsnCd = rtrnRsnCd; } public String getSellToCustCd() { return sellToCustCd; } public void setSellToCustCd(String sellToCustCd) { this.sellToCustCd = sellToCustCd; } public List<RMA_LINE> getRmaLines() { return rmaLines; } public void setRmaLines(List<RMA_LINE> rmaLines) { this.rmaLines = rmaLines; } public String toString() { return "ID:" + this.id + ", RMA_NUM:" + this.rmaNum + ", Status:" + this.rmaHdrStsCd + ", Type:" + this.rtrnTpCd + ", Reason:" + this.rtrnRsnCd; } }
@Id private RmaLinePk rmaLinePk;
Above:In “many side”, it uses the primary key field
package com.ns.spring.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.ManyToOne; import javax.persistence.JoinColumn; import javax.persistence.Id; import javax.persistence.Table; /** * Entity bean with JPA annotations Hibernate provides JPA implementation */ @Entity @Table(name = "RMA_LINE") public class RMA_LINE { @Id private RmaLinePk rmaLinePk; @Column(name = "rma_line_sts_cd") private String rmaLineStsCd; @Column(name = "mdse_cd") private String mdseCd; @Column(name = "qty") private int qty; @ManyToOne @JoinColumn(name = "rma_id") private RMA_HDR rmaHdr; public RMA_LINE(){} public RmaLinePk getRmaLinePk() { return rmaLinePk; } public void setRmaLinePk(RmaLinePk rmaLinePk) { this.rmaLinePk = rmaLinePk; } public String getRmaLineStsCd() { return rmaLineStsCd; } public void setRmaLineStsCd(String rmaLineStsCd) { this.rmaLineStsCd = rmaLineStsCd; } public String getMdseCd() { return mdseCd; } public void setMdseCd(String mdseCd) { this.mdseCd = mdseCd; } public RMA_HDR getRmaHdr() { return rmaHdr; } public int getQty() { return qty; } public void setQty(int qty) { this.qty = qty; } public void setRmaHdr(RMA_HDR rmaHdr) { this.rmaHdr = rmaHdr; } public String toString() { return "PK:" + this.rmaLinePk.toString() + ", Line Status:" + this.rmaLineStsCd + ", Mdse:" + this.mdseCd + ", Qty:" + this.qty; } }
private String rma_num; private String rma_line_num;
The real primary keys which are composite defines in the following class: RmaLinePk.java
package com.ns.spring.model; import java.io.Serializable; import javax.persistence.Embeddable; @Embeddable public class RmaLinePk implements Serializable { private static final long serialVersionUID = -403250971215465050L; private String rma_num; private String rma_line_num; public RmaLinePk() { } public RmaLinePk(String rma_num, String rma_line_num) { this.rma_num = rma_num; this.rma_line_num = rma_line_num; } public String getRma_num() { return rma_num; } public void setRma_num(String rma_num) { this.rma_num = rma_num; } public String getRma_line_num() { return rma_line_num; } public void setRma_line_num(String rma_line_num) { this.rma_line_num = rma_line_num; } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } RmaLinePk other = (RmaLinePk) obj; if (rma_num == null) { if (other.rma_num != null) { return false; } } else if (!rma_num.equals(other.rma_num)) { return false; } if (rma_line_num == null) { if (other.rma_line_num != null) { return false; } } else if (!rma_line_num.equals(other.rma_line_num)) { return false; } return true; } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((rma_num == null) ? 0 : rma_num.hashCode()); result = prime * result + ((rma_line_num == null) ? 0 : rma_line_num.hashCode()); return result; } public String toString() { return "RmaLinePk:RMA#:" + this.rma_num + ", Line#:" + this.rma_line_num; } }
This is how the data is stored in controller: See also Submitting a collection.
public ModelAndView submitLine(@ModelAttribute("rmaLineListModel") RmaLineListModel rmaLineListModel, Model model, HttpServletRequest req) { String rmaNum = rmaLineListModel.getRmaNum(); List<RmaLineModel> currList = rmaLineListModel.getRmaLineModelList(); if (!CommonBL.isEmpty(currList)) { for (RmaLineModel obj : currList) { String rmaLineNum = obj.getRmaLineNum(); List<RmaLineModel> rmaLinsList = RmaDtlBL.getRmaLineListWithCdTblNm(rmaNum, rmaLineNum); if (CommonBL.isEmpty(rmaLinsList)) { // New Record this.rmaLineSvc.save(RmaDtlBL.getRmaLineObj(obj, rmaNum, rmaLineNum)); } } } List<RmaLineModel> rmaLineModelList = RmaDtlBL.getRmaLineListWithCdTblNm(rmaNum, null); return getMVSubLine01(rmaNum, rmaLineModelList, req); }
This method passes the object to be inserted/updated
public static RMA_LINE getRmaLineObj(RmaLineModel obj, String rmaNum, String rmaLineNum) { RMA_LINE rmaLine = new RMA_LINE(); rmaLine.setRmaLinePk(new RmaLinePk(rmaNum, rmaLineNum)); rmaLine.setRmaHdr(RmaBL.getRmaHdrObj(rmaNum)); rmaLine.setRmaLineStsCd(getStsCd(obj.getRmaLineStsCd())); rmaLine.setMdseCd(obj.getMdseCd()); rmaLine.setQty(obj.getQty()); return rmaLine; }