Spring MVC 3.0.5 with Hibernate and Maven project
I’ve just started trying to piece together a Spring MVC project with Hibernate and Maven in Eclipse. So far it has been VERY frustrating as Eclipse wasn’t publishing the app with the lib files. That took over an hour of my time up and I haven’t yet managed to get it to run. I will update the following when I finally get it working, but here are the basics of what I have so far Ok, I’ve got it working finally. Turns out there are some unusual settings files that contain relevant paths for web app deployment. The following have been updated and should work:
MyObject.java
package uk.co.vsf.MyApp.database.beans;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class MyObject
{
@Id
private Integer myId;
public MyObject(Integer myId)
{
this.myId = myId;
}
public void setMyId(Integer myId)
{
this.myId = myId;
}
public Integer getMyId()
{
return myId;
}
}
AbstractDAO.java
package uk.co.vsf.MyApp.database.dao;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.criterion.Projections;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
class AbstractDAO<T> extends HibernateDaoSupport implements IDAO<T>
{
protected final Log log = LogFactory.getLog(getClass());
protected Class<T> entityClass;
protected String tableName;
protected String orderFieldName;
public AbstractDAO(final String tableName, final String orderFieldName, final Class<T> entityClass)
{
this.tableName = tableName;
this.orderFieldName = orderFieldName;
this.entityClass = entityClass;
}
/** {@inheritDoc} */
public void save(final T transientInstance)
{
log.debug("About to save object of type " + entityClass);
try
{
getHibernateTemplate().save(transientInstance);
log.debug("Saved");
}
catch ( final RuntimeException re )
{
log.error("Failed to save object of type " + entityClass, re);
throw re;
}
}
/** {@inheritDoc} */
public void delete(final T persistentInstance)
{
log.debug("About to delete instance of " + entityClass);
try
{
getHibernateTemplate().delete(persistentInstance);
log.debug("Delete successful");
}
catch ( final RuntimeException re )
{
log.error("Failed to delete instance of " + entityClass, re);
throw re;
}
}
/** {@inheritDoc} */
public T findById(final String id)
{
log.debug("About to find instance of " + entityClass + " with id: " + id);
try
{
final T instance = (T) getHibernateTemplate().get(this.entityClass, id);
return instance;
}
catch ( final RuntimeException re )
{
log.error("Failed to find instance of " + entityClass + " with id: " + id, re);
throw re;
}
}
@SuppressWarnings("unchecked")
/** {@inheritDoc} */
public List<T> findAll()
{
log.debug("About to find all instances of " + entityClass);
try
{
String queryString = "FROM " + tableName;
queryString += " ORDER BY " + orderFieldName;
return getHibernateTemplate().find(queryString);
}
catch ( final RuntimeException re )
{
log.error("Failed to find all instances of " + entityClass, re);
throw re;
}
}
@SuppressWarnings("unchecked")
/** {@inheritDoc} */
public int getRowCount()
{
log.debug("About to get a row count of table " + tableName);
try
{
final Criteria criteria = this.getSession(false).createCriteria(this.entityClass);
criteria.setProjection(Projections.rowCount());
final List<Integer> results = criteria.list();
return results.get(0);
}
catch ( final RuntimeException re )
{
log.error("Failed to get row count of table " + tableName, re);
throw re;
}
}
/** {@inheritDoc} */
public T merge(final T detachedInstance)
{
log.debug("Merging instance of type " + entityClass);
try
{
final T result = (T) getHibernateTemplate().merge(detachedInstance);
log.debug("Merged succesfully");
return result;
}
catch ( final RuntimeException re )
{
log.error("Merge of instance type " + entityClass + " failed", re);
throw re;
}
}
/** {@inheritDoc} */
public void deleteAll()
{
log.debug("About to delete all records from the " + tableName);
try
{
// flush all changes to the database to avoid issues when deleting.
this.getHibernateTemplate().flush();
final int rows = this.getHibernateTemplate().bulkUpdate("delete from " + tableName);
log.debug("successfully " + rows + " deleted");
this.getHibernateTemplate().clear();
}
catch ( final RuntimeException re )
{
log.error("Failed to delete all rows from " + tableName, re);
throw re;
}
}
/** {@inheritDoc} */
public void flushAndClear()
{
try
{
flush();
this.getHibernateTemplate().clear();
}
catch ( final RuntimeException re )
{
log.error("Failed to flush and clear the cache", re);
throw re;
}
}
/** {@inheritDoc} */
public void flush()
{
try
{
this.getHibernateTemplate().flush();
}
catch ( final RuntimeException re )
{
log.error("Failed to flush the cache", re);
throw re;
}
}
/** {@inheritDoc} */
public T update(final T instance)
{
return merge(instance);
}
/**
* Limits the number of results given the start position and the number of results required.
*
* @param criteria
* criteria object to apply limit to
* @param start
* the start position of the limit, E.g. row 15 = 15
* @param fetchSize
* the amount to fetch, E.g. 20 rows.
*/
protected void limitCriteria(final Criteria criteria, final int start, final int fetchSize)
{
criteria.setFirstResult(start);
criteria.setFetchSize(fetchSize);
criteria.setMaxResults(fetchSize);
}
}
IDAO.java
package uk.co.vsf.MyApp.database.dao;
import java.util.List;
public interface IDAO<T>
{
/**
* Save an instance to the table.
*
* @param instance
* row to add to table
*/
void save(T instance);
/**
* Delete the supplied instance from the database table.
*
* @param instance
* to delete from the table
*/
void delete(T instance);
/**
* Finds the specific instance in the database which matches the 'id' passed in.
*
* @param id
* Id to find in database
* @return the instance with the given id, or <code>null</code> if it is not found.
*/
T findById(String id);
/**
* Find all instances in a table. The SQL equivalent is - select * from table.
*
* @return List of table rows
*/
List<T> findAll();
/**
* Returns the row count for the particular table.
*
* @return the number of rows in the table
*/
int getRowCount();
/**
* Merge changes.
*/
T merge(T detachedInstance);
/**
* Delete all instances from the database. Equivalent to delete from table.
*/
void deleteAll();
/**
* Flushes the changes in the cache to the database and clears the cache. If any stored
* procedures or native sql code is used, this must be called first.
*/
void flushAndClear();
/**
* Flushes the changes in the cache to the database.
* ALWAYS run before a stored procedure!
*/
void flush();
/**
* Update the instance.
*/
T update(T instance);
}
MyDAO.java
package uk.co.vsf.MyApp.database.dao;
import uk.co.vsf.MyApp.database.beans.MyObject;
public class MyDAO extends AbstractDAO<MyObject>
{
public MyDAO()
{
super("MyObject", "id", MyObject.class);
}
/*
* final Criteria criteria = getSession(false).createCriteria(MyObject.class);
* criteria.createAlias("myObjectsReferenceEntityName", "tableLink1");
* criteria.add(Restrictions.eq("tableLink1.myField2", 1));
* criteria.add(Restrictions.isNotNull("field1"));
* criteria.setProjection(Projections.rowCount());
* final List<MyObject> myObjects = criteria.list();
*/
}
IMyController.java
package uk.co.vsf.MyApp.presentation.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
public interface IMyController
{
@RequestMapping(value = "/page1.html")
ModelAndView page1(final String order, final String direction);
@RequestMapping(value = "/page2.html")
ModelAndView page2();
}
IMyController.java
package uk.co.vsf.MyApp.presentation.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import uk.co.vsf.MyApp.database.dao.MyDAO;
@Controller
public class MyController implements IMyController
{
@Autowired
private MyDAO myDAO;
public void setMyDAO(final MyDAO myDAO)
{
this.myDAO = myDAO;
}
public ModelAndView page1(@RequestParam(value = "order", required = false) final String order,
@RequestParam(value = "direction", required = true) final String direction)
{
return null;
}
/** {@inheritDoc} */
public ModelAndView page2()
{
final ModelAndView mav = new ModelAndView("mypage");
mav.addObject("myvar", 1);
mav.addObject("myobjects", myDAO.findAll());
return mav;
}
}
hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<mapping class="uk.co.vsf.MyApp.database.beans.MyObject"/>
</session-factory>
</hibernate-configuration>
log4j.properties
log4j.rootCategory=ERROR, FILEROLLER, CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=[MyApp] %d{dd MMM yyyy HH:mm:ss,SSS} %p: [%t %C{1}.%M(%L)] : %m%n log4j.appender.FILEROLLER=org.apache.log4j.RollingFileAppender log4j.appender.FILEROLLER.layout=org.apache.log4j.PatternLayout log4j.appender.FILEROLLER.layout.ConversionPattern=[MyApp] %d{dd MMM yyyy HH:mm:ss,SSS} %p: [%t %C{1}.%M(%L)] : %m%n log4j.appender.FILEROLLER.File=${catalina.home}/logs/myApp.log log4j.appender.FILEROLLER.MaxFileSize=105MB log4j.appender.FILEROLLER.MaxBackupIndex=3 log4j.appender.FILEROLLER.threshold=DEBUG # If programmed properly the most messages would be at DEBUG and the least at FATAL. #log4j.logger.com.tripLog=INFO log4j.logger.uk.co.vsf.MyApp=DEBUG
mypage.jsp
<html>
<head>
<?php if (isCseAllowed()) {
echo "<link rel=\"preload\" href=\"https://cse.google.com/cse.js?cx=007066816790183607535:cjruhgzse8h\" as=\"script\">";
echo "<script async src=\"https://cse.google.com/cse.js?cx=007066816790183607535:cjruhgzse8h\"></script>";
} ?>
<?php if (isA2aAllowed()) {
echo "<link rel=\"preload\" href=\"/wp-content/plugins/add-to-any/addtoany.min.css\" as=\"style\">";
echo "<link rel=\"preload\" href=\"https://static.addtoany.com/menu/page.js\" as=\"script\">";
} ?>
<link rel="preload" href="/wp-content/themes/vsf/style.css" as="style">
<link rel="preload" href="/wp-content/uploads/2016/10/cropped-vsf-1-32x32.png" as="image">
<link rel="preload" href="/wp-content/uploads/2016/10/cropped-vsf-1-192x192.png" as="image">
<link rel="preload" href="/wp-content/uploads/2016/10/cropped-vsf-1-180x180.png" as="image">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<%
final String TEST_VAR = "myVAR";
%>
</head>
<body>
${myobjects}
</body>
</html>
applicationContext-datasource.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/scales"/>
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="maxActive" value="25"/>
<property name="maxIdle" value="10"/>
<property name="maxWait" value="-1"/>
<property name="removeAbandoned" value="true"/>
<property name="removeAbandonedTimeout" value="60"/>
<property name="logAbandoned" value="true"/>
<property name="accessToUnderlyingConnectionAllowed" value="true"/>
<property name="initialSize" value="1"/>
</bean>
</beans>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--<bean id="myManager" class="uk.co.v-s-f.myApp.MyManager" autowire="byType"/>-->
<bean id="myDAO" class="uk.co.vsf.MyApp.database.dao.MyDAO" autowire="byType">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
</beans>
myApp-servlet.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:oxm="http://www.springframework.org/schema/oxm"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="uk.co.vsf.MyApp" />
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/webpages/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
web.xml
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-datasource.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<servlet>
<servlet-name>myApp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>detectAllViewResolvers</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myApp</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
.classpath
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry excluding="**/*.java" kind="src" output="target/classes" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry exported="true" kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry exported="true" kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
.project
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>myApp</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.maven.ide.eclipse.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.maven.ide.eclipse.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>uk.co.v-s-f</groupId>
<artifactId>MyApp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>MyApp</name>
<properties>
<version.spring>3.0.5.RELEASE</version.spring>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${version.spring}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.3.1.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.13</version>
</dependency>
<dependency>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.9.0.GA</version>
</dependency>
</dependencies>
</project>
org.eclipse.wst.common.component
<?xml version="1.0" encoding="UTF-8"?>
<project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="MyApp">
<wb-resource deploy-path="/" source-path="/WebContent"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<property name="context-root" value="MyApp"/>
<property name="java-output-path" value="/MyApp/target/classes"/>
</wb-module>
</project-modules>
So once that’s all been put in the relevant directories, it should look something like this:
I’m going to be adding ExtJS to this soon, so check back in a month or two to see ExtJS integration.
Please enable the Disqus feature in order to add comments