MySQL + Hibernate + spring-data-jpa + Java Config

Lets Create a Web based User Application (very Simple which has id and name) With following

  • Maven
  • Spring -MVC
  • spring-data-jpa
  • Hibernate
  • MySQL
  • JNDI

I use eclipse IDE to create a “Dynamic Web Application”

i have selected the “Dynamic web module” as  3.0 because i need to use this application to deploy in the SAP HANA Cloud, which is explained in next post

eclipseproject

And i have configures the Maven project for the same See pom.xml

 <dependencies>
 <dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-core</artifactId>
 </dependency>
 <dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-entitymanager</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-webmvc</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework.data</groupId>
 <artifactId>spring-data-jpa</artifactId>
 </dependency>
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 </dependency>
 <dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>jstl</artifactId>
 <scope>provided</scope>
 </dependency>
 <dependency>
 <groupId>jstl</groupId>
 <artifactId>jstl</artifactId>
 <version>1.2</version>
 </dependency>
 <!-- Logging -->
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-api</artifactId>
 <scope>runtime</scope>
 </dependency>

 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>jcl-over-slf4j</artifactId>
 <scope>runtime</scope>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <scope>runtime</scope>
 </dependency>

 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <exclusions>
 <exclusion>
 <groupId>javax.mail</groupId>
 <artifactId>mail</artifactId>
 </exclusion>
 <exclusion>
 <groupId>javax.jms</groupId>
 <artifactId>jms</artifactId>
 </exclusion>
 <exclusion>
 <groupId>com.sun.jdmk</groupId>
 <artifactId>jmxtools</artifactId>
 </exclusion>
 <exclusion>
 <groupId>com.sun.jmx</groupId>
 <artifactId>jmxri</artifactId>
 </exclusion>
 </exclusions>
 <scope>runtime</scope>
 </dependency>
 </dependencies>

Now Lets create the entity call User

package com.chiru.test.user;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class User {
@Id
@GeneratedValue
private int id;
private String name;
//Getter and setters
}

The DAO which is using spring-data-jpa as below

package com.chiru.test.user;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserDAO extends CrudRepository<User, Integer> {

}

Yes, That’s it.  power of spring-data-jpa

Now the Spring MVC Controller

package com.chiru.test.user;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class UserController {

 @Autowired
 private UserDAO userDao;

 @RequestMapping("/")
 public ModelAndView getAllusers(ModelAndView modelAndView) {
 modelAndView.setViewName("userlist");
 modelAndView.addObject("users", userDao.findAll());
 return modelAndView;
 }

 @RequestMapping("/user")
 public ModelAndView save(ModelAndView modelAndView) {
 modelAndView.setViewName("userForm");
 return modelAndView;
 }

 @RequestMapping(value = "/user/save", method = RequestMethod.POST)
 public ModelAndView save(@RequestParam(value = "userName") String userName, ModelAndView modelAndView) {
 User user = new User();
 user.setName(userName);
 userDao.save(user);
 modelAndView.addObject("userName", userName);
 modelAndView.setViewName("success");
 return modelAndView;
 }
}

And i will not put the code for the view part, you can download it.

Lets configure the Web application with the Spring Java Config

1: Configure the Web Application:

package com.chiru.test.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class UserApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

 @Override
 protected Class<?>[] getRootConfigClasses() {
 return new Class[] { SpringAppConfig.class,HibernateConfig.class};
 }

 @Override
 protected Class<?>[] getServletConfigClasses() {
 return null;
 }

 @Override
 protected String[] getServletMappings() {
 return new String[] { "/" };
 }
}

2: Spring MVC configuration

package com.chiru.test.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan("com.saartha")
@Import(HibernateConfig.class)
public class SpringAppConfig {
 @Bean 
 public InternalResourceViewResolver setupViewResolver() { 
 InternalResourceViewResolver resolver = new InternalResourceViewResolver(); 
 resolver.setPrefix("/WEB-INF/views/"); 
 resolver.setSuffix(".jsp"); 
 resolver.setViewClass(JstlView.class); 
 return resolver; 
 }
}

3: Hibernate and JPA with JNDI Configuration.

package com.chiru.test.config;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories(basePackages={"com.chiru.test.user"})//1
@EnableTransactionManagement//2
public class HibernateConfig {
 
 @Bean//3
 public DataSource getDataSource() {
 final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
 dsLookup.setResourceRef(true);
 DataSource dataSource = dsLookup.getDataSource("jdbc/DefaultDB");
 return dataSource;
 }
 
 @Bean//4
 public JpaTransactionManager transactionManager(
 EntityManagerFactory entityManagerFactory) {
 JpaTransactionManager transactionManager = new JpaTransactionManager();
 transactionManager.setEntityManagerFactory(entityManagerFactory);
 return transactionManager;
 }
 
 @Bean//5
 public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
 LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = 
 new LocalContainerEntityManagerFactoryBean();
 entityManagerFactoryBean.setDataSource(this.getDataSource());
 entityManagerFactoryBean
 .setJpaVendorAdapter(new HibernateJpaVendorAdapter());
 entityManagerFactoryBean.setPackagesToScan("com.chiru.test.user");

 entityManagerFactoryBean.setJpaProperties(this.hibProperties());

 return entityManagerFactoryBean;
 }
 //6
 private Properties hibProperties() {
 Properties properties = new Properties();
 properties.put("hibernate.dialect","org.hibernate.dialect.MySQLDialect");
 properties.put("hibernate.hbm2ddl.auto","create");
 properties.put("hibernate.default_schema","userschema");
 return properties;
 }
}

1: We have to enable the JPA Repository by giving the base packages, so all the @Entity will be scanned by spring for Persistance

2: We need to enable the Transaction manager

3: We are creating the Datasource which is from JNDI, The JNDI name is “jdbc/DefaultDB”, this will be configured in the web.xml and Tomcat’s contex.xml as below

web.xml

<web-app 
..
<resource-ref>
 <description>DB Connection</description>
 <res-ref-name>jdbc/DefaultDB</res-ref-name>
 <res-type>javax.sql.DataSource</res-type>
</resource-ref>
..
</web-app>

context.xml

<Context ...>
...
<Resource
 name="jdbc/DefaultDB"
 auth="Container"
 type="javax.sql.DataSource"
 maxActive="100"
 maxIdle="30"
 maxWait="10000"
 driverClassName="com.mysql.jdbc.Driver"
 url="jdbc:mysql://localhost:3306/users"
 username="root"
 password="root"
 />
</Context>

4: Transaction Manager is configured (Spring-ORM)

5:Entity Manager for JPA (Spring-JPA)

6: Hibernate properties like default schema name, hbm2ddl.auto and dialect

So we can run this from eclipse.