Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to declare final fields for Hibernate-managed objects?

Tags:

I'm just getting started with Hibernate, and all the examples I'm seeing so far look pretty much like the tutorial in the Hibernate documentation:

package org.hibernate.tutorial.domain; import java.util.Date;  public class Event {      private Long id;     private String title;     private Date date;      public Event() {}      /* Accessor methods... */ } 

Specifically: none of the fields are declared as final, and there must be a no-argument constructor so that the Hibernate framework can instantiate the class and set its fields.

But here's the thing - I really don't like making my classes mutable in any way whenever I can avoid it (Java Practices: Immutable Objects make a pretty strong argument for doing this). So is there any way to get Hibernate to work even if I were to declare each of the fields 'final'?

I understand that Hibernate uses Reflection to instantiate its classes and therefore needs to be able to invoke a constructor of some sort without taking the risk that it would pick the wrong constructor or pass the wrong value to one of its parameters, so it's probably safer to invoke the no-arg constructor and set each field one at a time. However, shouldn't it be possible to provide the necessary information to Hibernate so that it can safely instantiate immutable objects?

public class Event {      private final Long id;     private final String title;     private final Date date;      public Event(@SetsProperty("id") Long id,         @SetsProperty("title") String title,         @SetsProperty("date") Date date) {          this.id = id;         this.title = title;         this.date = new Date(date.getTime());     }      /* Accessor methods... */ } 

The @SetsProperty annotation is of course fictitious, but doesn't seem like it should be out of reach.

like image 534
Kyle Krull Avatar asked May 26 '09 18:05

Kyle Krull


People also ask

What impact does making an entity bean final in hibernate have?

In short, making a JPA Entity or Hibernate Persistence class final, limits the ability of Hibernate to use Proxies, which in turn prevents Hibernate from applying some performance optimizations.

What is POJO class in hibernate?

POJO stands for Plain Old Java Object. In simple terms, we use POJO to make a programming model for declaring object entities. The classes are simple to use and do not have any restrictions as compared to Java Beans.

How do you hibernate a user?

To use Hibernate you need to create a helper class that handles startup and that accesses Hibernate's SessionFactory to obtain a Session object. The class calls Hibernate's configure() method, loads the hibernate. cfg. xml configuration file and then builds the SessionFactory to obtain the Session object.

How does Java Hibernate work?

Hibernate reduces lines of code by maintaining object-table mapping itself and returns result to application in form of Java objects. It relieves programmer from manual handling of persistent data, hence reducing the development time and maintenance cost.


2 Answers

Actually in JDK 1.5+ hibernate can handle (through reflection) changing final fields. Create a protected default constructor() that sets the fields to some defaults/null etc... Hibernate can and will override those values when it instantiates the object.

This is all possible thanks to changes to Java 1.5 memory model - the changes of interest (allowing final to be not so final) where made to enable serialization/deserialization.

public class Event {  private final Long id; private final String title; private final Date date;  // Purely for serialization/deserialization protected Event() {     id = null;     title = null;     date = null; }  public Event(Long id, String title, Data date) {     this.id = id;     this.title = title;     this.date = date; }  /* Accessor methods... */ 

}

like image 133
Andy Avatar answered Sep 21 '22 21:09

Andy


Immutable object means an object with no methods that modify its state (i.e. its fields). The fields needn't be final. So you can remove all mutators and configure Hibernate to use fields acces instead of accessors or you can just mark no-arg constructor and mutators as deprecated. It's a bit workaround but better that than nothing.

like image 31
Tadeusz Kopec for Ukraine Avatar answered Sep 19 '22 21:09

Tadeusz Kopec for Ukraine