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;
}