Hibernate Read Only Entity
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
Contents
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(); } }
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(); } }
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(); } }
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 usingCriteria
, 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(); } }
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' }