Spring + Hibernate Config

hiv-mvc-img

To make your Spring MVC program work with Hibernate, Following files need to be modified:

For more info, see: Spring MVC Config

<beans:bean id="dataSource" 
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <beans:property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <beans:property name="url"      value="jdbc:mysql://localhost:3306/ns201501" />
    <beans:property name="username" value="root" />
    <beans:property name="password" value="nobu" />
</beans:bean>

This is a part of servlet-context.xml. In this case, DB is MySQL.

<!-- Hibernate 4 SessionFactory Bean definition -->
<beans:bean id="hibernate4AnnotatedSessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <beans:property name="dataSource" ref="dataSource" />
    <beans:property name="annotatedClasses">
        <beans:list>
            <beans:value>com.ns.spring.model.RMA_HDR</beans:value>
            <beans:value>com.ns.spring.model.RMA_LINE</beans:value>
            <beans:value>com.ns.spring.model.RTRN_TP</beans:value>
            <beans:value>com.ns.spring.model.RTRN_RSN</beans:value>
            <beans:value>com.ns.spring.model.RTRN_TP_RSN</beans:value>
            <beans:value>com.ns.spring.model.RTRN_TP_RSN_CMBN</beans:value>
            <beans:value>com.ns.spring.model.RMA_HDR_STS</beans:value>
            <beans:value>com.ns.spring.model.MDSE</beans:value>
            <beans:value>com.ns.spring.model.RmaLinePk</beans:value>
            <beans:value>com.ns.spring.model.RtrnTpRsnPk</beans:value>
            <beans:value>com.ns.spring.model.ui.RmaHdrModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RmaHdrStsModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RmaLineModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RtrnRsnModel</beans:value>
            <beans:value>com.ns.spring.model.ui.RtrnTpModel</beans:value>
        </beans:list>
    </beans:property>
    <beans:property name="hibernateProperties">
        <beans:props>
            <beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</beans:prop>
            <beans:prop key="hibernate.show_sql">true</beans:prop>
        </beans:props>
    </beans:property>
</beans:bean>

This part defines the classes for CRUD operation. For example, line 7 is the class for Hibernate object (below) represent the table RMA_HDR.

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();
	}
	// getter and setter
}
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
;
<!-- Hibernate -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>${hibernate.version}</version>
</dependency>
<!-- Apache Commons DBCP -->
<dependency>
    <groupId>commons-dbcp</groupId>
    <artifactId>commons-dbcp</artifactId>
    <version>1.4</version>
</dependency>
<!-- MySQL -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.9</version>
</dependency>

This is a part of pom.xml. As line 18 to 23, DB is MySQL.

Multiple Row Form Submit

submit-multi-form2
In biz apps, it is a common requirement that the data stays in the screen but not in the data base. And it’s pretty painful, compared to insert the record every time the user add it.

Suppose your screen displaying a list, and you have added more than one rows at once (But not in the Database yet)
submit-multiple-rows1
Once submitted, the added rows are in the Database:
submit-multiple-rows2

Summarized as two steps:

  1. The each row added one by one in the screen
  2. All rows are inserted/updated to the Database

@RequestMapping(value = "/cUrlValAttrbSubLine01Jsp", params = "addItemSubLine01", method = RequestMethod.POST)
public ModelAndView addItemSubLine01(@ModelAttribute("rmaLineListModel") RmaLineListModel rmaLineListModel, Model model, HttpServletRequest req) {
	
	ModelAndView modelAndView = new ModelAndView(VIEW.SUB_LINE_01.getVal());
	modelAndView.addObject(CONST.FORM_KEY.getVal(), rmaLineListModel);

	String rmaNum = rmaLineListModel.getRmaNum();
	String mdseCd = rmaLineListModel.getMdseCd();
	String mdseNm = CommonBL.getMdseNm(CommonBL.getMdse(mdseCd));
	List<RmaLineModel> currList = rmaLineListModel.getRmaLineModelList();
	
	RmaLineModel newRow = new RmaLineModel();
	newRow.setRmaNum(rmaNum);
	newRow.setRmaLineNum(RmaDtlBL.getNewLineNum(currList));
	newRow.setMdseCd(mdseCd);
	newRow.setMdseNm(mdseNm);
	currList.add(newRow);
	
	rmaLineListModel.setRmaLineModelList(currList);		
	modelAndView.addObject(CONST.LINE_LIST_MODEL.getVal(), rmaLineListModel);
	modelAndView.addObject(CONST.HDR_STS_LIST.getVal(), CommonBL.getStsList(req));	
	return modelAndView;
}

At Step 1, in the Controller method, line between 12 to 17, adding a new Object added to the list

@RequestMapping(value = "/cUrlValAttrbSubLine01Jsp", params = "submitLine", method = RequestMethod.POST)
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);
}

At Step 2, in the Controller, it takes a parameter (Model class) contains a list, and the three added rows are now added.

Submitting a Form

submit-form-img1
Unlike updating a part of screen by Ajax, this is a traditional(?), and a basic way: to Submit an entire form.

Summarized as three steps:

  1. SUBMIT button is pressed, and passes an Forms (Object) to the controller method.
  2. The Controller method takes the Object and Register (Insert/Update) to the data base
  3. Return a String as JSP name

The Detail of Step 1
submit-form-take-param1

@RequestMapping(value = "/cUrlValAttrbMain01Jsp", params = "submitHdr", method = RequestMethod.POST)
public String submitHdr(@ModelAttribute("RmaHdrModel") RmaHdrModel rma, HttpServletRequest req) {
	RmaBL.saveHdr(rma, req);
	return VIEW.REDIRECT_HOME.getVal();
}

1.1.cUrlValAttrbMain01Jsp” is defined in main_01.jsp.

<c:url var="addAction" value="/cUrlValAttrbMain01Jsp.html" ></c:url>
<form:form action="${addAction}" commandName="rmaMapKey">

1.2.submitHdr” is “name” attribute in “Submit” button in main_01.jsp.

<input type="submit" value="Submit" name="submitHdr" style="height:25px; width:150px; color: #F6FDA4; background-color: #CC0000; font-face: 'Comic Sans MS';"/>

1.3. @ModelAttribute specifies an argument in the Controller class RmaController.java.
1.4. The parameter “RmaHdrModel rma” takes the form object from JSP.


The Detail of Step 2 & 3
submit-form-step-2-3

@RequestMapping(value = "/cUrlValAttrbMain01Jsp", params = "submitHdr", method = RequestMethod.POST)
public String submitHdr(@ModelAttribute("RmaHdrModel") RmaHdrModel rma, HttpServletRequest req) {
	RmaBL.saveHdr(rma, req);
	return VIEW.REDIRECT_HOME.getVal();
}

2.1. RmaBL.saveHdr does insert/update to the Database

public static RMA_HDR saveHdr(RmaHdrModel rma, HttpServletRequest req) {
	RMA_HDR obj = new RMA_HDR(rma);
	if (rma.getId() == 0) {
		hdrSvc.save(obj);
		// Set RMA# with formatted
		DecimalFormat df = new DecimalFormat("000000");
		obj.setRmaNum("RMA" + df.format((double) obj.getId()));
	}
	hdrSvc.update(obj);
	req.getSession().removeAttribute(CONST.HDR_LIST.getVal());
	return obj;
}

3.1.VIEW.REDIRECT_HOME.getVal()” returns a string “redirect:/ns-home” from a constant class and redirect to the method initialize the screen

enum VIEW {
	
	MAIN_01("main_01"),
	SUB_LINE_01("sub_line_01"),
	SUB_TP_01("sub_tp_01"),
	SUB_RSN_01("sub_rsn_01"),
	SUB_TP_RSN_01("sub_tp_rsn_01"),
	REDIRECT_HOME("redirect:/ns-home")
	;
	
	private String code;

	VIEW(String code) {
		this.code = code;
	}

	public String getVal() {
		return code;
	}
}