Hibernate + JPA + Spring-data-jpa + HANA Database

In my previous post we have created a HANA Database(Row) and we have created a Web application to create and see the Users with MySQL

Now lets change the application to work with HANA DB and In SAP HANA Cloud Platform.

1: We need to Access the Database Using JNDI Data Source, Change the Data Source Name as below in the HibernateConfig.java (see the post User App With MySQL)

@Bean
 public DataSource getDataSource() {
 final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
 dsLookup.setResourceRef(true);
 DataSource dataSource = dsLookup.getDataSource("jdbc/DefaultDB");
 return dataSource;
 }

If You are using the HANA Cloud Trail Version we can create only one DataSource that is so the datasource name should be “jdbc/DefaultDB”, other name will not be considered. (Creating the Datasource Name(binding) for the HANA Database we will see in the next step).

2: Change the Hibernate Dialect in the hibProperties() method in the  HibernateConfig.java (see the post User App With MySQL)

Properties properties = new Properties();
 properties.put("hibernate.dialect","org.hibernate.dialect.HANARowStoreDialect");
 properties.put("hibernate.hbm2ddl.auto","create");
 properties.put("hibernate.default_schema","CHIRU");

Dialect is “org.hibernate.dialect.HANARowStoreDialect” Because we have created Row Databse.

hibernate.default_schema should be Database user name which we have created for the Database(refer my previous post ), because the HANA will create the Schema in the USERNAME. I think its only for Trail version.

3: We need to Create the (Data Source Bindings) for the HANA Database.

To do this first we need to deploy the Java application first. follow the post to Deploy the Java web application.

After deploying the application login to the SAP HANA Cloud Platform Cockpit

  1. Click on the “Databases & Schemas”, select the Database which you need to bind for this application
  2. Now we can see the overview screen
  3. Select “Data Source Bindings” from the left navigation panel.
  4. click on “New binding”binding
  5. Data source name Should be , see the Step 1.
  6. select the Java Application
  7. Give the user name which is created in the previous post.
  8. password for the User.

Need to restart the Java Application to take new binding.

Source Code

Hibernate + JPA + Spring-data-jpa + HANA Database

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.

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