DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Modify JSON Data in Postgres and Hibernate 6
  • Providing Enum Consistency Between Application and Data
  • How to Store Text in PostgreSQL: Tips, Tricks, and Traps
  • Develop XR With Oracle Cloud, Database on HoloLens, Ep 2: Property Graphs, Data Visualization, and Metaverse

Trending

  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • Accelerating Debugging in Integration Testing: An Efficient Search-Based Workflow for Impact Localization
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  • Cloud Security and Privacy: Best Practices to Mitigate the Risks
  1. DZone
  2. Data Engineering
  3. Databases
  4. Implement Hibernate Second-Level Cache With NCache

Implement Hibernate Second-Level Cache With NCache

Set up a Java application with Hibernate, configure NCache as the second-level cache, and test the implementation to see how caching reduces the DB load.

By 
Abhinav Pandey user avatar
Abhinav Pandey
·
Oct. 22, 24 · Tutorial
Likes (3)
Comment
Save
Tweet
Share
7.4K Views

Join the DZone community and get the full member experience.

Join For Free

In this tutorial, we'll explore implementing a second-level cache in Hibernate using NCache.

We'll set up a Java application with Hibernate. Then we'll configure NCache as the second-level cache. Finally, we'll test the implementation to see how caching reduces the database load and improves performance.

Basics

Before we dive into the implementation, let's understand the basics of Hibernate, NCache, and Hibernate second-level cache.

Hibernate

Hibernate is an open-source object-relational mapping (ORM) framework for Java applications. It simplifies the development of database interactions by mapping Java objects to database tables and vice versa.

To improve performance, Hibernate provides two levels of caching:

1. First-Level Cache

The first-level cache is associated with the Hibernate session and is enabled by default. It stores the objects retrieved during a session and eliminates the need to hit the database multiple times for the same object.

The first-level cache is limited to the scope of a session and is not shared across sessions.

It is also not persistent and is cleared when the session is closed or cleared explicitly.

2. Second-Level Cache

The second-level cache is shared across sessions and can be configured to cache data at the application level. It reduces the number of database hits by storing objects longer.

Second-level cache needs to be configured explicitly and can be implemented using various caching providers like NCache, Ehcache, etc.

NCache

NCache is a distributed caching solution for .NET and Java applications. It provides an in-memory data store that can be used to cache frequently accessed data and improve application performance.

NCache supports various caching topologies like replicated, partitioned, and client cache.

NCache can be used as a second-level cache in Hibernate to store and retrieve objects from the cache instead of hitting the database.

Code Setup

Let's start by creating a Java application and setting up Hibernate to interact with the database.

We'll use Maven to manage dependencies and build the project. The application will have an entity class to define the data and a client class to interact with the database.

First, we'll test the application without caching to see the database interactions. Then, we'll configure NCache as the second-level cache in Hibernate to cache the entity objects and reduce database hits.

Dependencies

We'll start by adding the required dependencies for Hibernate and NCache in the pom.xml file:

<dependencies> <!-- Hibernate dependencies --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>6.6.1.Final</version> </dependency> <!-- NCache dependencies --> <dependency> <groupId>com.alachisoft.ncache</groupId> <artifactId>ncache-hibernate</artifactId> <version>5.3.3</version> </dependency> </dependencies>


Please note that the versions mentioned here may vary based on the latest releases. Make sure to use the appropriate versions for your project.

Entity Class

Next, let's create an entity class to represent the data we want to cache. We'll define a simple Customer class with id and name fields:

@Entity @Cacheable @org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE, region = "CustomerRegion") public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; // getters and setters }


The Customer class is annotated with @Entity and @Cacheable to define it as a cacheable entity. It has an id field annotated with @Id and @GeneratedValue to generate unique identifiers automatically.

We also use the @Cache annotation to specify the caching strategy and region for the entity.

NONSTRICT_READ_WRITE tells Hibernate to update the cache when data is read or written with eventual consistency.

The region attribute specifies the cache region where the data will be stored.

We'll configure NCache to use this region to store the cached data.

Hibernate Configuration

We need to configure Hibernate to interact with the database and enable caching.

Let's create a hibernate.cfg.xml file in the src/main/resources directory with the following configuration:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">password</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">true</property> </session-factory> </hibernate-configuration>


In this configuration file, we specify the database connection details, dialect, and cache settings. We use Oracle as the database and configure Hibernate to update the schema automatically.

Client Class

Let's create a client class to interact with the database and test the caching mechanism. We can write a main class to save and retrieve Customer objects using Hibernate:

public class HibernateClient { public static void main(String[] args) { SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = session.beginTransaction(); Customer customer = new Customer(); customer.setName("John Doe"); session.save(customer); transaction.commit(); session.close(); session = sessionFactory.openSession(); transaction = session.beginTransaction(); Customer retrievedCustomer = session.get(Customer.class, customer.getId()); System.out.println("Retrieved Customer: " + retrievedCustomer.getName()); transaction.commit(); session.close(); session = sessionFactory.openSession(); transaction = session.beginTransaction(); retrievedCustomer = session.get(Customer.class, customer.getId()); System.out.println("Retrieved Customer: " + retrievedCustomer.getName()); transaction.commit(); session.close(); } }


In this client class, we create a SessionFactory using the Hibernate configuration and open a session to interact with the database. We save a Customer object to the database and retrieve it using the id.

Then we call the retrieveCustomer method twice in two separate sessions to see the database interactions without caching.

We'll observe that the database is hit twice to retrieve the same object:

Database is hit twice to retrieve the same object

As we can see, the Hibernate query is executed twice.

Setting up the NCache Server

To use NCache as the second-level cache in Hibernate, we need to set up an NCache server and configure it to store the cached data.

NCache provides a distributed caching solution that can be installed on Windows and Linux servers. We'll create a cache cluster using NCache and configure it. Once the cache cluster is set up, we can connect to it from our Java application.

Enabling NCache as Second Level Cache in Hibernate

Once the NCache server is set up, we can configure Hibernate to use NCache as the second-level cache provider. We'll update the Hibernate configuration file and specify the cache settings to enable caching.

Enabling Cache Regions

Let's update the cache settings in the hibernate.cfg.xml file to enable NCache as the second-level cache provider:

<hibernate-configuration> <session-factory> <property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.region.factory_class">com.alachisoft.ncache.NCacheRegionFactory</property> ... </session-factory> </hibernate-configuration>


Here, we set the hibernate.cache.use_second_level_cache property to true to enable the second-level cache. We also specify the hibernate.cache.region.factory_class property to use the NCacheRegionFactory, an implementation of the JCacheRegionFactory, as the cache provider.

Configuring NCache Properties

NCache provides a set of properties to configure the cache settings in Hibernate. We can specify these in the ncache-hibernate.xml file:

<configuration> <application-config application-id="myapp" enable-cache-exception="true" default-region-name="DefaultRegion" key-case-sensitivity="false"> <cache-regions> <region name="CustomerRegion" cache-name="demoCache" priority="AboveNormal" expiration-type="Sliding" expiration-period="8"/> <region name="DefaultRegion" cache-name="demoCache" priority="default" expiration-type="None" expiration-period="0"/> </cache-regions> <database-dependencies> <dependency entity-name="hibernator.BLL.Customer" type="oledb" sql-statement="SELECT CustomerID FROM Customers WHERE CustomerID ='?';" cache-key-format="Customers#[pk]" connection-string="Provider=SQLOLEDB;Data Source=20.200.20.40,1433;Initial Catalog=Northwind;User ID=john;Password=1234;"/> </database-dependencies> </application-config> </configuration>


In this configuration file, we define the CustomerRegion cache region with the cache name, priority, expiration type, and expiration period. We set the expiration-type to Sliding with an expiration period of 8 seconds. This means that the cached data will expire after 8 seconds of inactivity and will be removed from the cache.

Additionally, we define a DefaultRegion with default settings for other entities that do not have a specific cache region. This is used as a fallback region for entities that are not explicitly configured.

Having multiple cache regions allows us to define different cache settings for different entities based on their requirements.

Next, we define a database dependency for the Customers entity. This is used to keep the cache in sync with the database and update/remove the cached data when changes are made in the database.

We specify the SQL statement to retrieve the CustomerID from the Customers table and the connection string to connect to the database.

The cache key format specifies how the cache key is generated based on the primary key of the entity.

Testing

Now that we have configured NCache as the second-level cache in Hibernate, let's test the application to see how caching improves performance. We'll run the client class again and observe the database interactions with caching enabled.

Run the client class again and observe the database interactions with caching enabled

When we run the client class, we'll see that the first call to retrieve the Customer object hits the database to fetch the data. However, the second call to retrieve the same object will fetch it from the cache instead of hitting the database again. This demonstrates how caching reduces the database load and improves performance by serving data from the cache.

Benefits of Using NCache With Hibernate

Using NCache as the second-level cache in Hibernate provides several benefits:

  • Improved performance: NCache provides fast in-memory storage for cached data, reducing latency and improving throughput. It also provides async operations to update the cache in the background, reducing the impact on application performance.
  • Scalability: As the application scales, NCache can scale horizontally to handle large amounts of data and user requests. It can be deployed in a cluster and supports features like cache replication and partitioning to distribute the load.
  • Flexibility: NCache provides various caching topologies and configurations to meet different application requirements. Moreover, due to the use of cache regions, different entities can have different cache settings based on their needs. This allows fine-grained control over caching behavior.
  • Synchronization: NCache provides the option of database synchronization to keep the cache in sync with the database. This ensures that the cached data is up-to-date and reflects the latest changes made in the database.

Summary

In this tutorial, we explored implementing a second-level cache in Hibernate using NCache for Java applications.

We started by understanding the basics of Hibernate, NCache, and Hibernate second-level cache. Then, we set up a Java application with Hibernate and configured NCache as the second-level cache. Finally, we tested the implementation to see how caching improves performance by reducing database hits and serving data from the cache.

By using NCache with Hibernate, developers can enhance the performance, scalability, and reliability of their applications by leveraging the power of distributed caching. NCache provides a robust caching solution that integrates seamlessly with Hibernate and other Java frameworks, making it an ideal choice for caching data in Java applications.

Database Cache (computing) Data (computing) Dependency Hibernate Property (programming)

Opinions expressed by DZone contributors are their own.

Related

  • Modify JSON Data in Postgres and Hibernate 6
  • Providing Enum Consistency Between Application and Data
  • How to Store Text in PostgreSQL: Tips, Tricks, and Traps
  • Develop XR With Oracle Cloud, Database on HoloLens, Ep 2: Property Graphs, Data Visualization, and Metaverse

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!