Does the latest Hibernate method provide the ability to create a proxy server for such an object?

Hibernate uses proxies to provide lazy loading of collections and even substandard associations. According to the Hibernate help documentation (3.6.5) (Section 21.1.3, Single-Link Proxies), such a proxy server cannot be constructed by Hibernate if it contains “any final methods”.
My question is, does this restriction apply to getters / setters of constant fields or is it really to any method in an entity class? So, does the method do this:

public final String toString() { return this.getClass().getSimpleName() + id; } 

really prevents the creation of a proxy server (CGLIB or Javassist) for this object? Does it matter if field or property access is used? Since CGLIB has been superseded by Javassist, does this provide additional features in this direction?

I like to use inheritance in my object hierarchy, and therefore the requirement to define some final methods, for example, in a base class to prevent overriding these subclasses.

early!

+6
source share
3 answers

Using the Hibernate mailing list (thanks to Emmanuel Bernard!) I can answer my own question: summary: The final methods do not prevent Hibernate from creating a proxy server at all, but if these methods do not use any state of the entity, it is extremely impractical.

Some background information: Hibernate does not use bytecode amplification with either cglib or Javassist, so for a proxy to initialize its target entity lazily, it must intercept any method that can use the state of this target. Now it’s perfectly normal to have a final method like this

 public final doSomething(String a, Integer b ) { // do complicated stuff using only a and b (no instance members accessed!) } 

but as soon as this method uses some constant field directly or through another instance method , it will bypass the proxy server and thus lead to unexpected behavior.

As a side element, this is the same reason why you should not directly access the fields of other instances, for example, in equals entity methods:

 // XXX bad code! public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Profile)) return false; Profile profile = (Profile) o; // XXX this bypasses a possible proxy, use profile.getName() instead! return (name == null ? profile.name == null : name.equals(profile.name)); } 
+6
source

I am sure that, as the link says, this applies to any method. In fact, the proxy server, in my opinion, is nothing more than a subclass of the object, which initially has no state except the identifier of the object, and which delegates the call of each method to the actual instance of the entity class after its initialization. Therefore, he must override all methods to

  • initialize itself if necessary
  • delegate a call to the actual instance method
+1
source

Inspired by this question, I created a plugin for Intellij IDEA that solves this problem. There he is:

https://plugins.jetbrains.com/plugin/7866

A simple description is as follows:

Sleeping silence fails in certain situations, leading to errors that are difficult to track. This plugin helps to find and fix some of these problems. In the "Settings"> "Inspections"> "Hibernation" section of the inspection, he adds the following checks: • The saved class is final; • The final persistent class method uses direct field access.

================================================

Note:

As @BartvanHeukelom explained in the comments, the fact that the final methods cannot be proxied can be used as an asset: then you can get the object identifier from the recipient, without initializing the proxy and loading its fields. This is the code I'm using:

 @SuppressWarnings ("AccessingFieldFromAFinalMethodOfPersistedClass") public final Id getId() { if (this instanceof HibernateProxy) return (Id)((HibernateProxy)this).getHibernateLazyInitializer().getIdentifier(); else return id; } 

Check out @SuppressWarnings . This is only necessary if you are using IntelliJ IDEA with my plugin.

0
source

Source: https://habr.com/ru/post/892216/


All Articles