How to convert a Hibernate proxy to a real entity object
Here's a method I'm using.
public static <T> T initializeAndUnproxy(T entity) {
if (entity == null) {
throw new
NullPointerException("Entity passed for initialization is null");
}
Hibernate.initialize(entity);
if (entity instanceof HibernateProxy) {
entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}
JPA/Hibernate proxy not fetching real object data, sets all properties to null
As JB Nizet suggested, the final modifier in my classes' getters was messing with the proxies hibernate creates for lazy loaded relationships.
how to unproxy a hibernate object
Here's our solution, added to our persistence utils:
public T unproxy(T proxied)
{
T entity = proxied;
if (entity instanceof HibernateProxy) {
Hibernate.initialize(entity);
entity = (T) ((HibernateProxy) entity)
.getHibernateLazyInitializer()
.getImplementation();
}
return entity;
}
Hibernate returns proxy for base class
Can't be certain without seeing more of the object model, but one reason Hibernate would do this is if the BaseEntity had already had to be resolved as a proxy for the same BaseEntity.id
earlier in the session.
For example, if there is another class that has a ToOne relation to a BaseEntity
, it will just have a foreign key to the id
, so will use a BaseEntity_$$...
proxy to delay resolving the correct subclass for the other end. This then becomes the instance for that id
that is managed in the Hibernate PersistenceContext
.
Clearly a Hibernate.unwrap()
, or one of the other options in the link above will reveal the 'true' instance. One other option is to use abstract methods on BaseEntity
(e.g. isIndividual()
). This can look a bit tidier, but ultimately Hibernate will still need to resolve the proxy when the method is called.
How does Hibernate implement Proxy Objects?
Hibernate use javassist to create dynamic proxies instead of concrete entities to populate fields of fetched entity that are referencing other persistent entity (or collection of persistent entities).
(note that if you mark the relationship as eagerly fetched : hibernate won't create proxies but concrete entities. This is NOT the default)
A major advantage of javassist over standard dynamic proxy mechanism is that it allows creation of dynamic proxy on concrete classes, not only interfaces.
The responsability of a proxy is to perform "transparently" a database read operation when required (i.e. when access to a proxied entity is required)
Proxies and first or second level cache aren't really linked concepts. We can just say that if you try to "resolve" a proxy when the entity holding it isn't attached to an open session (i.e. when the entity holding it isn't in the first level cache) it will raise a LazyInitializationException (simply because there is no way perform a database read in this situation)
How to retrieve an Entity Object just with @Id (Proxy object), check if it exists and assign it to a @ManyToOne association
I don't understand what the problem is. Just use getOne
approach and at the end of your method, use flush
which will throw the constraint violation exception that you can handle. This is the way to go.
Related Topics
Scanner VS. Stringtokenizer VS. String.Split
Why Use a Prime Number in Hashcode
Avoid Jackson Serialization on Non Fetched Lazy Objects
Javafx Fxml Controller - Constructor VS Initialize Method
"Program to an Interface". What Does It Mean
Sorting a Collection of Objects
How to Wire One Pane to Another
Display Indeterminate Jprogressbar While Batch File Runs
Jformattedtextfield Is Not Properly Cleared
Converting Array to List in Java
Initial Bytes Incorrect After Java Aes/Cbc Decryption
String, Stringbuffer, and Stringbuilder
What Is Suppresswarnings ("Unchecked") in Java
Differencebetween Thread.Start() and Thread.Run()
What Is the Default Initialization of an Array in Java
How to Convert Byte Size into a Human-Readable Format in Java