Sunday, March 2, 2014

Spring WEB-MVC Project Setup (Pure Java Based Configurations) with Using Spring Data

Introduction:

Hello friends, thanks to like my last post of "Spring WEB-MVC Project Setup (Pure Java Based Configuration) without using Database". This new Post is based on previous post and in this post, we use same project with "Spring Data" and spring database configurations are done using Pure Java Classes. For create this post, there are so many Google search help me and most import spring documentation, Spring Accessing Data with JPA and Fruzenshtein's notes. They help me create a good example for how to use Java Based configuration and how to use Spring Data. If you want to download the source of examples, please checkout from My Git Repository

Spring Data: 

Spring Data, provide a way to remove boilerplate code from our project and make our application more reliable. For performing CRUD operation with database, every developer need to create some base template class, which provide some CRUD functionality to perform Database Operation. But all this things are now handle by spring data easily. Spring data easily work with SQL and NO-SQL databases. 

In this i only cover Database configuration and some database classes for handle DB operations, and web based classes are same as previous post. There are some minor changes in web configuration java classes and pom.xml which we discuss in this post. I am using MySQL as a DB.    

Step 1:

Our package structure of example is in screen shot:


Step 2:

Create DBConfiguration.java file for database configuration. The code is following : 

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories("com.springjavaconfig.repository")
public class DBConfiguration {

private static final String PROPERTY_NAME_DATABASE_URL = "jdbc:mysql://localhost/spring_test"; 
private static final String PROPERTY_NAME_DATABASE_DRIVER = "com.mysql.jdbc.Driver";  
    private static final String PROPERTY_NAME_DATABASE_USERNAME = "root";  
    private static final String PROPERTY_NAME_DATABASE_PASSWORD = "root";
    
    @Bean
    public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setUrl(PROPERTY_NAME_DATABASE_URL);
    dataSource.setDriverClassName(PROPERTY_NAME_DATABASE_DRIVER);
    dataSource.setUsername(PROPERTY_NAME_DATABASE_USERNAME);
    dataSource.setPassword(PROPERTY_NAME_DATABASE_PASSWORD);;
   
    return dataSource;
    }
    
    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPersistenceProviderClass(HibernatePersistence.class);
    factoryBean.setPackagesToScan("com.springjavaconfig.entity"); //  use Spring-based scanning for entity classes in the classpath
    factoryBean.setJpaVendorAdapter(jpaVendorAdapter());
    return factoryBean;
    }

private JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setShowSql(true);
jpaVendorAdapter.setDatabase(Database.MYSQL);
jpaVendorAdapter.setGenerateDdl(true);
return jpaVendorAdapter;
}
@Bean
public JpaTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}

  1. @Configuration annotation we discuss in our previous POST. 
  2. @EnableTransactionManagement : This annotation is similar <tx:*/> tag in xml based configuration. This is used to enable transaction with the using of annotations. It provide some more flexibility then <tx:*/>. In xml, we are not assign flexible name to the bean, but with this annotation we are flexible to assign the name of the bean. for more detail Click on this link.
  3. @EnableJpaRepositories : This annotation scan the repository of Spring Data and in the arguments we pass the package structure of spring data repository. String Data repository provide Implementation of CRUD operation with entities. 
In this class we create data source, entity manager and transaction beans. And configure JPA implementation provide by Hibernate. We use default data source, but it depends on you, you also used your own data source implementation or used Apache DBCP or any other. For JPA implementation you will use any vendor like top link, eclipse link etc. For more details of classes, please follow spring documentation. 

Step 3:

Create an Entity Class for perform some CRUD operations. 

@Entity
public class User implements Serializable{
/**
*/
private static final long serialVersionUID = -3012564413270146956L;
private Integer id;
private String name;
private int age;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
        
        @Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}

Step 4:

Create a class for Spring Data Repository. 

public interface UserRepo extends CrudRepository<User, Integer> {
}

This interface contain empty body. but it extends CrudRepository interface. This is Spring Data interface provide some implementation for performing CRUD operation with our entity. This is generic interface and we pass or entity and ID for maintain our entity. Spring Data provide some more interface for provide some more functionality with the CRUD operationks like pagination etc. The implementation of these interfaces are abstract. For more detail Click on this link. There is one more interface in Spring DATA is JPARepository. For difference between CrudRepository and JPARepository Click here.

Step 5:

In previous step we create Spring Data Repository, now we provide some CRUD operation that perform by these repository. we use some abstract layer for hide the implantation of Spring Data Repository. 

public interface UserService {

public User save(User user);
public List<User> findAll();
}

Step 6:

In this step we create implementation of abstract layer and use repository to perform CRUD operation with entity. 

@Service
public class UserServiceImpl implements UserService {

@Resource
private UserRepo userRepo;
@Override
@Transactional
public User save(User user) {
return userRepo.save(user);
}

@Override
@Transactional
public List<User> findAll() {
return Lists.newArrayList( userRepo.findAll());
}
}

In this step we only cover two operations save and find-all, but you can also use some more operations like delete, findById etc. for this please check Spring Data Documentation. 

Step 7:

Create a controller class for handle Http Requests : 

@Controller
public class FirstController {

@Autowired
private UserService userService;
@RequestMapping(value="/saveuser", method=RequestMethod.POST)
public String saveUser(String name, int age){
User user = new User();
System.out.println("name : "+name+" ******** age : "+age);
user.setName(name);
user.setAge(age);
System.out.println(userService.save(user));
return "helloworld";
}
@RequestMapping(value="/getallusers", method=RequestMethod.GET)
public String getAllUser() {
List<User> users = userService.findAll();
for(User user : users){
System.out.println(user.toString());
}
return "helloworld";
}
}

Step 8: 

Create some HTML or JSP pages for input : 

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Index</title>
</head>
<body>
<h1>Index File</h1><br />
<form action="saveuser" method="post">
<table>
<tr>
<td>Name : </td>
<td><input type="text" name="name"/></td>
</tr>
<tr>
<td>Age : </td>
<td><input type="text" name="age"/></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Submit"/></td>
</tr>
</table>
</form>
<br />
<a href="getallusers">Click here to get all users, and check the output on server console</a>
</body>
</html>

Step 9:

There are some few changes in Web Configuration Java File that we use in previous POST. We add some new annotations only : 

@Configuration
@EnableWebMvc
@Import({DBConfiguration.class})
@ComponentScan({"com.springjavaconfig.web", "com.springjavaconfig.service.impl"})
public class WebAppConfig extends WebMvcConfigurerAdapter{
@Bean
public UrlBasedViewResolver setupViewResolver(){ 
--------------------------------------------

The @Import annotation is used to import more configuration file in main configuration file. We add new package name in @ComponentScan annotation, for scan some more components in java packages. 

Step 10: 

There are some changes in pom.xml file. we need to add some more dependencies for spring data and add some maven plugins for handle maven task easily. 

<properties>
<spring-version>4.0.0.RELEASE</spring-version>
<jdk.version>1.7</jdk.version>
</properties>

<!-- Spring Dependencies -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</version>
</dependency>

<!-- Servlet Dependencies -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<!-- Database and Spring data Dependencies -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring-version}</version>
</dependency>

<!-- Hibernate for JPA implementation -->
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.9.Final</version>
</dependency>
<!-- Mysql JDBC drivers -->

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
            
<!-- use some extra libraries for java collections -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>r09</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<!-- If we not need to include web.xml in our war file like in servelet 
3.0 -->
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>

Mostly maven provide some default functionality to create war file, but the default implementation some time creates a problem and some time we need to modify war file structure. So we need to add war file plugins. The other plugins in maven compiler plugins maven 3.X provide JDK 1.5 compiler implementation, so if we need to use JDK new version or different version, we need to add maven compiler plugins. With my experience i realize that maven default plugins create some problem, which irritate the developer. So i think we always need to add some maven plugins for handle some specific task. So, if i am wrong  please correct me or If any other user have some more experience with spring data or any other technology, please share the knowledge. 

No comments:

Post a Comment