Class cast exception with Hibernate and Javassist / CGILib

ClassCastException:

<your_entity_impl>_$$_javassist_29 cannot be cast to <your interface>

If you ever encounter class cast exceptions when explicitly casting Hibernate / JPA Entities to subclasses, say because of an

@Inheritance(strategy = InheritanceType.JOINED)

type of Entity – you will soon find out that this is basically the dark side of ORM optimisation. This is largely due toe the fact that Hibernate uses Javassist and CGILib proxies, instead of the instance itself, which then again implements the entities interface directly, thus ignoring the rest of the inheritance structure. The upside is that this proxied approach is much faster, the downside is it breaks the initial class structure.

This can be avoided by “de-proxying” your instance, by either visiting every lazy member (cumbersome) or explicitly declaring each relationship as FetchType.EAGER (which is slow and kind of dumb).

Another, slightly less annoying method has been largely described in the hibernate forums:

https://forum.hibernate.org/viewtopic.php?f=1&t=987738&start=0

The gist of it is to provide a utility method which you use instead of your cast:

   public static <T> T deproxy(Object maybeProxy, Class<T> baseClass) throws ClassCastException {
      if (maybeProxy instanceof HibernateProxy) {
         return baseClass.cast(((HibernateProxy) maybeProxy).getHibernateLazyInitializer().getImplementation());
      }
      return baseClass.cast(maybeProxy);
   }

This is also kind of dumb, but less painful than the other options.

Advertisements
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s