Case 1 - Using SessionFactory

We will use the following steps to integrate Hibernate in our application using SessionFactory:

  1. Create a Java application named Ch03_Spring_Hibernate_Integration, and add to it JARs for Spring, JDBC, and Hibernate, as shown in the following screenshot:

You can download the ZIP containing jar for the Hibernate framework from http://hibernate.org/orm/downloads.

  1. Copy or create Book.java in the com.packt.ch03.beans package.
  2. Create book.hbm.xml in the classpath to map the Book class to the book_hib table, as shown in the following configuration:
<hibernate-mapping> 
  <class name="com.packt.ch03.beans.Book"table="book_hib"> 
  <id name="ISBN" type="long"> 
    <column name="ISBN"/> 
    <generator class="assigned"/> 
  </id> 
  <property name="bookName" type="java.lang.String"> 
    <column name="book_name"/> 
  </property> 
  <property name="description" type="java.lang.String"> 
    <column name="description"/> 
  </property> 
  <property name="author" type="java.lang.String"> 
    <column name="book_author"/> 
  </property> 
  <property name="price" type="int"> 
    <column name="book_price"/> 
  </property> 
  </class> 
</hibernate-mapping>

Here, the configuration of tags used in the book.hbm.xml file is as follows:

    • id: This defines mapping for the primary key from the table to the book class
    • property: This provides mapping of data members to the columns in the table
  1. Add the BookDAO interface, as we did in the Ch03_JdbcTemplate application.
  2. Implement BookDAO by BookDAO_SessionFactory, and override the methods from the BookDAO interface. Annotate the class with @Repository. Add a data member of type SessionFactory annotated with @Autowired. The code is shown as follows:
@Repository(value = "bookDAO_sessionFactory") 
public class BookDAO_SessionFactory implements BookDAO { 
  @Autowired 
  SessionFactory sessionFactory; 
  
  @Override 
  public int addBook(Book book) { 
    // TODO Auto-generated method stub 
    Session session = sessionFactory.openSession(); 
    Transaction transaction = session.beginTransaction(); 
    try { 
      session.saveOrUpdate(book); 
      transaction.commit(); 
      session.close(); 
      return 1; 
    } catch (DataAccessException exception) { 
      exception.printStackTrace(); 
    } 
    return 0; 
  } 
 
  @Override 
  public int updateBook(longISBN, intprice) { 
    // TODO Auto-generated method stub 
    Session session = sessionFactory.openSession(); 
    Transaction transaction = session.beginTransaction(); 
    try { 
      Book book = session.get(Book.class, ISBN); 
      book.setPrice(price); 
      session.saveOrUpdate(book); 
      transaction.commit(); 
      session.close(); 
      return 1; 
    } catch (DataAccessException exception) { 
      exception.printStackTrace(); 
    } 
    return 0; 
  } 

  @Override 
  public boolean deleteBook(longISBN) { 
    // TODO Auto-generated method stub 
    Session session = sessionFactory.openSession(); 
    Transaction transaction = session.beginTransaction(); 
    try { 
      Book book = session.get(Book.class, ISBN); 
      session.delete(book); 
      transaction.commit(); 
      session.close(); 
      return true; 
    } catch (DataAccessException exception) { 
      exception.printStackTrace(); 
    } 
    return false; 
  } 
} 
  1. Add connection_new.xml to configure SessionFactory and other details, as shown in the following piece of code:
<context:annotation-config /> 
  <context:component-scan base-package="com.packt.ch03.*">
</context:component-scan> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <!-properties for dataSource--> </bean> <bean id="sessionFactory" class= "org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mappingResources"> <list> <value>book.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <props> <prop key= "hibernate.dialect">org.hibernate.dialect.MySQLDialect </prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> </bean>
  1. Create or copy MainBookDAO_operations.java to get the bookDAO_sessionFactory bean to test the application. The code is as follows:
public static void main(String[] args) { 
  // TODO Auto-generated method stub 
  ApplicationContext context=new 
     ClassPathXmlApplicationContext("connection_new.xml"); 
  BookDAO bookDAO=(BookDAO)  
    context.getBean("bookDAO_sessionFactory"); 
  //add book 
  int rows=bookDAO.addBook(new Book("Java EE 7 Developer  
    Handbook", 97815674L,"PacktPub  
      publication",332,"explore the Java EE7  
      programming","Peter pilgrim")); 
  if(rows>0) 
   {  
     System.out.println("book inserted successfully"); 
   } 
   else 
   System.out.println("SORRY!cannot add book"); 
 
   //update the book 
   rows=bookDAO.updateBook(97815674L,432); 
   if(rows>0) 
   {  
     System.out.println("book updated successfully"); 
   } 
   else 
   System.out.println("SORRY!cannot update book"); 
 
   //delete the book 
   boolean deleted=bookDAO.deleteBook(97815674L); 
   if(deleted) 
   { 
     System.out.println("book deleted successfully"); 
   } 
   else 
   System.out.println("SORRY!cannot delete book"); 
 } 

We have already seen how to configure SessionFactory in the XML file. It extensively works with Transaction, but we have yet not discussed anything about transaction, its configuration, and how to manage it. We will discuss it in a later chapter

  1. For now, just execute the code, and get the operations performed one by one. Oops! Did we forget to set up the database and table creation? Actually not! We did the configuration of Sessionfactory, which has hibernate.hbm2ddl.auto as a property. This property helps in auto generation of the table in the database depending upon the configuration. So, just take advantage of Hibernate, and execute it.

The console output will also display the query fired to perform the database operation. The developer can get the information about the query only if they have configured the property show_sql as true. We have already done this!

Real-time applications handle a huge amount of data at each step. Let's say we want to find a book. Using hibernate, we will simply invoke a method that returns the book depending upon the ISBN of it. In day-to-day use, the book will be searched countless times, and each time, the database will be hit, leading to performance issues. Instead of this, it will be great to have a mechanism that will use the outcome of the previous query next time someone asks for it again. Spring 3.1 introduced an effective, yet simple way--a 'cache' mechanism--to achieve it, and added a JSR-107 annotation support in 4.1. The cached result will be stored in the cache repository of the selected queries. In normal applications, whenever the select query is fired, the database will get a hit in order to perform the database operation. However, if the configuration is done to store the result in the cache, instead of hitting the database, the database will be loaded from the cache. The functionality of cache is done in such a way that it will help in reducing the amount of database access or unnecessary hits to the database. You might be thinking of buffer, but it's different from cache. The buffer is an intermediate temporary storage to write and read data once. However, cache is hidden to improve the performance of an application, and from where the data is read multiple times.

The cache repository is the location where the objects fetched from the database will be saved in key-value pairs. Spring supports the following cache providers:

JDK ConcurrentMap cache

In JDK, ConcurrentMap is used as a backing cache store. Spring Framework has SimpleCacheManager to get CacheManager and give it a name. This cache is best for relatively small data, which doesn't change frequently. However, it cannot be used outside of Java heap to store data; also, there is no built-in way to share the data between multiple JVMs.

EHCache-based cache

EhcacheCacheManager is used to get a cache manager where the EHCache configuration specifications to be configured in the configuration file are generally named ehcache.xml. The developers can use different cache managers for different databases with different configurations.

Caffeine cache

Caffeine is a Java8-based caching library to provide high performance. It helps to overcome the important drawback of ConcurrentHashMap, which persists the data until explicitly removed. Along with it, it also provides automatic loading of data, expiration of data based on time, and provides notifications of the evicted data entries.

Spring provides both XML-based as well as annotation-based cache configuration. The easiest way is to use annotation-based configuration. From Spring 3.1 onwards, versions have enabled JSR-107 support. To take advantage of the cache using JSR-107, developers need to first perform cache declaration, which will help them identify the methods to be cached, and then, configure the cache to inform where the data is stored.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.29.145