...
hibernate collection cache

Hibernate Collection Cache: How to Use?

What is Hibernate Collection Cache?

Hibernate cache is a memory store that is used to store objects that have been read from the database. The hibernate collection cache can be accessed in many ways, including through JPA or through the Hibernate API.

Hibernate collection cache is an advanced feature in Hibernate. It is used for caching entire collections and can be configured to use either second-level or first level caches. Collection cache uses a single thread pool to access data sources and share the same database connection. This helps reduce the number of database connections needed by Hibernate during runtime which improves performance of your application.

Hibernate collection cache is a way to cache the collection of objects in memory. It’s an extension of the second level cache and can be used with any collection, including java.util collections like ArrayList, HashMap and so on.

How to Use Hibernate Collection Cache?

package bookentity.ejb;

/* * To change this template, choose Tools | Templates * and open the template in the editor. */

import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.ManyToMany;
import javax.persistence.JoinTable;
//import javax.persistence.JoinColumns;
import javax.persistence.JoinColumn;
import java.util.Collection;
import java.util.List;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
//import javax.persistence.inv
import javax.persistence.OneToMany;

@Entity
@Cacheable
@Table(name = "BOOK")
@NamedQueries({@NamedQuery(name="findBookByAuthorName",query="SELECT b FROM Book b,            Author a  WHERE  a.authorName=:authorName AND b = SOME(SELECT x FROM a.books x)"),
@NamedQuery(name="findBookByTitle",query="SELECT b FROM Book b WHERE   b.title=:bTitle")}) 

public class Book implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private int ISBN;
private String title;
private String description;
private Author author;
// @ManyToMany(fetch=FetchType.LAZY)
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name="BOOK_AUTHOR", joinColumns=@JoinColumn(name="BOOK_ID"),
inverseJoinColumns=@JoinColumn(name="AUTHOR_ID"))
private Collection<Author> authors;

 //@OneToMany(fetch=FetchType.EAGER, mappedBy="bookEntity")
  @OneToMany(fetch=FetchType.LAZY, mappedBy="bookEntity")
 public Collection<Review> reviews; 

   public Book() {
    authors = new ArrayList<Author>();
    reviews = new ArrayList<Review>();
}

public int getISBN() {
    return ISBN;
}

public void setISBN(int ISBN) {
    this.ISBN = ISBN;
}
public String getTitle(){
    return title;
}

 public void  setTitle(String title){
    this.title =  title;
}

  public String getDescription(){
    return description;
}

 public void  setDescription(String description){
    this.description =  description;
}
 public void addReview(Review review){
     if(!getReviews().contains(review)){
         getReviews().add(review);

     if(review.getBookEntity()!=null){
         review.getBookEntity().getReviews().remove(this);
     }
         review.setBookEntity(this);
     }
 }
 public void addAuthor(Author author){
     if  (!getAuthors().contains(author)){
             getAuthors().add(author);
       }
     if(!author.getBooks().contains(this)){
         author.getBooks().add(this);
     }
 }

 public Collection<Review> getReviews(){
     return reviews;
 }

 public Collection<Author> getAuthors(){
     return authors;
   }
     void setAuhorId(int authorID) {
    }
}

Here is the code for Author Entity:

  package bookentity.ejb;

import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.Cacheable;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import java.util.Collection;
import java.util.Hashtable;
import java.util.List;
import javax.naming.Context;
import javax.naming.InitialContext;


@Entity
@Cacheable
public class Author implements Serializable {
private static final long serialVersionUID = 1L;
@Id 
private int author_id;
String authorName;
 String authAddress;
@ManyToMany(mappedBy = "authors")
private Collection<Book> books;

public Author() { 
    books = new ArrayList<Book>();
}



public void setAuthor_id(int author_id) {
    this.author_id = author_id;

}


public int getAuthorId() {
    return this.author_id;
}

 public void setAuthorName(String  authorName) {
    this.authorName = authorName;
}

public String getAuthorName() {
    return authorName;
}
public String getAuthorAddress(){
    return this.authAddress;
}
 public void setAuthorAddress(String authAddress){
    this.authAddress = authAddress;
}

public Collection<Book> getBooks() {
   return books;

}


public void addBook(Book book){
    if(!getBooks().contains(book)) {
    getBooks().add(book);
    //book.getAuthors().add(this);
   }
if (!book.getAuthors().contains(this)){
    book.getAuthors().add(this);
  }
}

}

Here is the persistence.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="BookAuthorApp3-ejbPU" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider> 
<jta-data-source>java:/PostgresDS</jta-data-source>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/>   
<property name="hibernate.session_factory_name" value="SessionFactories/infinispan1" />
<property name="javax.persistence.sharedCache.mode" value="ALL" /> 
<property name="hibernate.cache.use_second_level_cache" value="true" />
<property name="hibernate.cache.use_query_cache" value="true" />  
<property name="hibernate.cacheable" value="true" /> 
<property name="hibernate.cache.use_structured_entries" value="true" />
<property name="hibernate.cache.infinispan.collection.cfg" value="entity" />
<property name="hibernate.cache.infinispan.bookentity.ej.Book.cfg" value="Books"/>
<property name="hibernate.cache.infinispan.bookentity.ej.Book.authors.cfg" value="Authors"/>
<property name="hibernate.cache.infinispan.statistics" value="true"/>
<property name="hibernate.generate_statistics" value="true" />   
<property name="hibernate.cache.region_prefix" value="infinispan" />
<property name="hibernate.cache.infinispan.entity.cfg" value="entity" />
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.JndiInfinispanRegionFactory" />
<property name="hibernate.cache.infinispan.cachemanager" value="java:CacheManager/entity" />
 </properties>

Here is the infinispan-configs.xml file

<infinispan-config name="hibernate" jndi-name="java:CacheManager/entity">
<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:infinispan:config:5.0    http://www.infinispan.org/schemas/infinispan-config-5.0.xsd" 
xmlns="urn:infinispan:config:5.0">  
<global>
<transport clusterName="${jboss.partition.name:DefaultPartition}-Hibernate" distributedSyncTimeout="17500">
<properties>
    <property name="stack" value="${jboss.default.jgroups.stack:udp}"/>
</properties>
</transport>
<globalJmxStatistics enabled="true"/>
<shutdown hookBehavior="DONT_REGISTER"/>
</global>
<default>
    <jmxStatistics enabled="false"/>
    <!--transaction transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossTransactionManagerLookup"/-->
</default>
<namedCache name="entity">
    <clustering mode="invalidation">
    <stateRetrieval fetchInMemoryState="false" timeout="20000"/>
    <sync replTimeout="20000"/>
    </clustering>
    <locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000"
             lockAcquisitionTimeout="15000" useLockStriping="false" />
    <eviction wakeUpInterval="5000" maxEntries="10000" strategy="LRU"/>
    <expiration lifespan = "-1" maxIdle="-1"/>   
    <lazyDeserialization enabled="true"/>
</namedCache>

How to enable or disable the collection cache

You can enable or disable the collection cache by using one of the following methods:

  • Configuring the collection cache through the configuration file.
  • Configuring the collection cache programmatically.
  • Configuring and enabling or disabling the collection cache in an XML file.

Hibernate Collection Cache

The Hibernate collection cache is a very powerful feature of Hibernate framework. It is used to store the collection elements in memory and not in database.

This feature improves the performance of application by reducing network calls between client and server, which increases performance. The hibernate can be used with any collections like List, Set, HashSet etc.

Conclusion

In this post we talked about the Hibernate Collection Cache. This is a feature that allows collections of objects to be stored and accessed within the database.