Skip to content

marcglasberg/HibernateInspectionsPlugin

Repository files navigation

Hibernate Inspections Plugin for IntelliJ IDEA

https://plugins.jetbrains.com/plugin/7866-hibernate-inspections

To install this plugin, in IntelliJ IDEA go to Settings > Plugins > Browse repositories, and select "Hibernate Inspections".

Do I need this plugin?

Yes! Hibernate silently fails in certain situations, without telling you where and why it is failing. It may even do the wrong thing, without giving you any warnings. This leads to bugs which can be very difficult to track down and fix.

This plugin helps you find and fix these problems.


In IntelliJ IDEA, under Settings > Inspections > Hibernate inspections it adds the following inspections:

  • Persisted class is final
  • Final method of a persisted class uses direct field access
  • Embeddable subclasses embeddable

Persisted class is final

This inspection reports when a persisted class is final (persisted with Hibernate or similar, annotated with @Entity, @MappedSuperclass, or @Embeddable).

From the Hibernate documentation:

A central feature of Hibernate, proxies (lazy loading), depends upon the persistent class being either non-final, or the implementation of an interface that declares all public methods. You can persist final classes that do not implement an interface with Hibernate; you will not, however, be able to use proxies for lazy association fetching which will ultimately limit your options for performance tuning.

There are 3 ways to solve this:

  • First is not to declare the class final.
  • Second is to disable proxy generation:
@Entity @Proxy(lazy=false) public class Cat { ... }

• Third is to tell Hibernate to use the interface instead (possible only when the final class implements a proper "full" interface):

@Entity @Proxy(proxyClass=ICat.class) public class Cat implements ICat { ... }

Note: This inspection only covers JPA/Hibernate annotated classes. It does not check XML file mappings.

More information:

Final method of a persisted class uses direct field access

This inspection reports when a final method of a persisted class (persisted with Hibernate or similar, annotated with @Entity, @MappedSuperclass, or @Embeddable) uses direct field access.

If a class is persisted (with Hibernate or similar), and proxies are on, a final method that directly accesses a field is ALWAYS a bug.

A final method does not prevent Hibernate from creating a proxy. Final methods that don't access state are fine. Final methods that only access state through another method are also fine. But the final method will fail (and may SILENTLY fail) if it uses a direct instance field, since field values will not be initialized (will be null, zero or false). There are 3 ways to solve this:

  • First is not to declare the method final.
  • Second is not to directly access fields from final methods.
  • Third is to disable proxy generation by setting lazy="false" (not recommended, for performance reasons).

Note 1: This inspection only covers JPA/Hibernate annotated classes. It does not check XML file mappings.

Note 2: If you use property access type strategy, you may access the identifier without forcing a proxy initialization. This isn’t true if you map the identifier property with direct field access type strategy; Hibernate then doesn’t even know that the getId() method exists. If you call it, the proxy has to be initialized. However, there is a way to avoid initializing the proxy even when using direct field access strategy. Just mark the getId() method as final, so that proxies cannot override it. Then, calling the method cannot run any proxy code, and thus cannot initialize the proxy. The method itself checks if its instance is a proxy, and in this case returns the id from the proxy. If the instance is the real object, it returns the id. This is a valid use (maybe the only one?) of a final method that directly accesses state in a proxyable persisted class. You should then suppress the warning generated by this inspection:

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

More information:

Embeddable subclasses embeddable

This inspection reports when an embeddable class subclasses another embeddable class (both annotated with @Embeddable).

As of June 2017, component inheritance is not supported by Hibernate (this may change in the future):

More information:

What happens when an embeddable class subclasses another embeddable class? Only the direct fields of the exact subclass declared in the entity that contains the component (the embeddable object) will be persisted. Also, the component creation may silently fail when loading the entity that contains the component (Hibernate will set it to null).

About

Hibernate (Java ORM) Inspections Plugin for the IntelliJ/Jetbrains IDE

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors