Deploy the Java web application to HANA Cloud

Here we deploy the war directly to the SAP HCP( HANA Could Platform) not from the Eclipse. Yes they do have written some tools for eclipse where we can connect to HANA Could and we can deploy from the eclipse.

In this we see the steps to deploy the Java Web application to SAP HCP. You need to follow some steps while developing the Dynamic web application in eclipse follow the below post for

  1. Creating the Dynamic web application
  2. Creating the HANA Database
  3. Creating the HANA Datasource binding
  4. Configure HANA database with Hibernate + JPA

Here we use the trail HANA Cloud account so we can deploy only one application.

1: Login to the SAP HCP Cockpit

2: Click on the “Java Applications” from the left side Navigation panel.

3: Click on “Deploy Application”. if you already have one you can delete the application but need to stop the application before deleting.(Note : if the binding is already created select the check box to say not to delete the binding).

4: Select the war file

deploywar

5: The name of the application will be generated automatically based on war file name.

6: Runtime has to select very carefully, check this link to chose Runtime, in our example we will use “Java Web Tomcat 7”

7: Other Things dont change, these are related to process and CPU’s other stuff we will not worry now.( even i dont know much about these, i have trail version 😦 ). these can be configured when we have licence in trail version they have some limitations.

8: Click “Deploy”, it will upload the .war file the it ask to start.

9. if you already have the data binding created you can start. Other wise just close.

10. To create binding follow the post last section.

11. Then Start the Application from SAP HCP Cockpit.

 

 

Deploy the Java web application to HANA Cloud

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