Hibernate Read Only Entity

By Arvind Rai, December 11, 2023
On this page, we will learn to make entity read only with Hibernate Session.setDefaultReadOnly(), Session.setReadOnly(), Query.setReadOnly(), Criteria.setReadOnly() and immutable entity. The read only entities cannot be modified. In hibernate, only persistent entities are read only, the transient and detached are not considered as read only entity. If the entities are immutable, then we need not to do anything to make it read only. Hibernate will automatically consider immutable entities read only. Find the complete example to make entity read only.

Find the sample Data Used in Demo
Hibernate Make Entity Read Only Example with Session.setDefaultReadOnly(), Session.setReadOnly(), Query.setReadOnly(),  Criteria.setReadOnly() and Immutable Entity

1. With Session.setDefaultReadOnly()


1. Session.setDefaultReadOnly(true) : After calling this method on Hibernate Session, all the persistent entities loaded from database are read-only. We can load entities from database using Session.load(), Session.get(), Session.merge() and in all cases the entities loaded will be read-only.
2. Session.setDefaultReadOnly(false): After calling this method, we set the default that persistent entities can be modified.
3. Session.isDefaultReadOnly() : It checks if default is read only. It returns Boolean value.

Before calling Session.setDefaultReadOnly(true), the entities loaded in Session will not be read-only. Now find the example.
SessionSetDefaultReadOnlyDemo.java
package com.concretepage;
import org.hibernate.Session;
public class SessionSetDefaultReadOnlyDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Book book0 = (Book)session.get(Book.class, 0);
		System.out.println("Book 0: "+book0.getBookName() +", "+ book0.getPrice());		
		session.setDefaultReadOnly(true);
		Book book1 = (Book)session.get(Book.class, 1);
		System.out.println("Book 1: "+book1.getBookName() +", "+ book1.getPrice());
		Book book2 = (Book)session.get(Book.class, 2);
		System.out.println("Book 2: "+book2.getBookName() +", "+ book2.getPrice());		
		session.beginTransaction();
		book0.setPrice(200);
		session.save(book0);
		book1.setPrice(300);
		session.save(book1);
		book2.setPrice(400);
		session.save(book2);		
		session.getTransaction().commit();
		session.flush();
		session.refresh(book0);		
		session.refresh(book1);
		session.refresh(book2);
		System.out.println("Book 0:"+book0.getBookName() +", "+ book0.getPrice());		
		System.out.println("Book 1:"+book1.getBookName() +", "+ book1.getPrice());
		System.out.println("Book 2:"+book2.getBookName() +", "+ book2.getPrice());		
		System.out.println("Is Default read only:"+ session.isDefaultReadOnly());
		session.close();
	}
} 
Here object book0 has been persistent in Session before calling session.setDefaultReadOnly(true), so it remains modifiable. But other two objects book1 and book2 are persistent in session after calling setDefaultReadOnly(true), so these two object are read only. When we update price, the read only objects remains unchanged. Find the output.
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book 0: PQR, 200
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book 1: STU, 100
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book 2: XYZ, 100
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book 0:PQR, 200
Book 1:STU, 100
Book 2:XYZ, 100
Is Default read only:true 

2. With Session.setReadOnly()


1. Session.setReadOnly(myEntityObj, true): Using this method we make persistent object read-only. We need to pass our object and Boolean value as true in the method as an argument if we want to make this persistent object read-only.
2. Session.setReadOnly(myEntityObj, false): By passing false value, we make our persistent entity modifiable if it was read-only before.

Find the example.
SessionSetReadOnlyDemo.java
package com.concretepage;
import org.hibernate.Session;
public class SessionSetReadOnlyDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Book book = (Book)session.get(Book.class, 1);
		System.out.println("Book: "+book.getBookName() +", "+ book.getPrice());
                session.setReadOnly(book, true);	
                session.beginTransaction();
                book.setPrice(500);
                session.save(book);
                session.getTransaction().commit();
                session.refresh(book);
                System.out.println("Book: "+book.getBookName() +", "+ book.getPrice());        
		session.close();
	}
} 
After making entity read only by calling session.setReadOnly(book, true), the changes in price will not affect it. Find the output.
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book: STU, 100
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book: STU, 100 

3. With Query.setReadOnly()

The entities returned from HQL can also be made read-only. Query.setReadOnly(true) sets the entities in query results as read-only. We need to call this method before Query.uniqueResult(), Query.scroll() , Query.iterate() or Query.list(). Other entities in Session before calling Query.setReadOnly(true) will be unaffected. Now find the example.
QuerySetReadOnlyDemo.java
package com.concretepage;
import org.hibernate.Query;
import org.hibernate.Session;
public class QuerySetReadOnlyDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Query query = session.createQuery("from Book as bk where bk.bookId = 1");
		query.setReadOnly(true);
		Book book = (Book)query.list().get(0);
		System.out.println("Book: "+book.getBookName() +", "+ book.getPrice());  
                session.beginTransaction();
                book.setPrice(500);
                session.save(book);
                session.getTransaction().commit();
                session.refresh(book);
                System.out.println("Book: "+book.getBookName() +", "+ book.getPrice());        
		session.close();
	}
} 
No effect of update on entity. Find the output.
Hibernate: select book0_.book_id as book_id1_0_, book0_.book_name as book_nam2_0_, book0_.price as price3_0_, book0_.writer as writer4_0_ from book book0_ where book0_.book_id=1
Book: STU, 100
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book: STU, 100 

4. With Criteria.setReadOnly()

In case we are using Criteria, we can call Criteria.setReadOnly(true) to make entities read-only. We need to call this method before Criteria.list(), Criteria.uniqueResult() or Criteria.scroll(). The entities loaded in Session before calling Criteria.setReadOnly(true) will be unaffected, if they are modifiable, then will remain modifiable.
CriteriaSetReadOnlyDemo.java
package com.concretepage;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
public class CriteriaSetReadOnlyDemo {
	public static void main(String[] args) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Criteria criteria = session.createCriteria(Book.class).add(Restrictions.eq("bookId", 1));
		criteria.setReadOnly(true);
		Book book = (Book)criteria.list().get(0);
		System.out.println("Book: "+book.getBookName() +", "+ book.getPrice());  
                session.beginTransaction();
                book.setPrice(500);
                session.save(book);
                session.getTransaction().commit();
                session.refresh(book);
                System.out.println("Book: "+book.getBookName() +", "+ book.getPrice());        
		session.close();
	}
} 
No effect of update on entity. Find the output.
Hibernate: select this_.book_id as book_id1_0_0_, this_.book_name as book_nam2_0_0_, this_.price as price3_0_0_, this_.writer as writer4_0_0_ from book this_ where this_.book_id=?
Book: STU, 100
Hibernate: select book0_.book_id as book_id1_0_0_, book0_.book_name as book_nam2_0_0_, book0_.price as price3_0_0_, book0_.writer as writer4_0_0_ from book book0_ where book0_.book_id=?
Book: STU, 100 

5. With Immutable Entity

In hibernate persistent entities will be read only if the entity is immutable. To create an entity immutable, we need to use @Immutable annotation. Find the complete example for immutable entity in the given link.

Example of @Immutable in Hibernate Annotation

Entity, Hibernate Utility, hibernate.cfg.xml and Gradle

Find the other files to run the demo.
Book.java
package com.concretepage;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="book")
public class Book {
	@Id
	@Column(name="book_id")
	private int bookId;
	@Column(name="book_name")
	private String bookName;
	@Column(name="price")
	private int price;	
	public int getBookId() {
		return bookId;
	}
	public void setBookId(int bookId) {
		this.bookId = bookId;
	}
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}	
} 

HibernateUtil.java
package com.concretepage;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
    private static SessionFactory sessionFactory ;
    static {
       Configuration configuration = new Configuration().configure();
       StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                      .applySettings(configuration.getProperties());
       sessionFactory = configuration.buildSessionFactory(builder.build());
    }
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}  

hibernate.cfg.xml
<hibernate-configuration>
  <session-factory>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">
    jdbc:mysql://localhost:3306/concretepage</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.connection.pool_size">10</property>
    <property name="show_sql">true</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <mapping class="com.concretepage.Book"/>
   </session-factory>
</hibernate-configuration> 

build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
archivesBaseName = 'hibernate'
version = '1' 
repositories {
    mavenCentral()
}
dependencies {
	compile 'org.hibernate:hibernate-core:4.3.8.Final'
	compile 'mysql:mysql-connector-java:5.1.34'
}  

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us