Question

I'm using Spring to develop my application using Hibernate and JPA as persistence API in a MySQL database. When I fetch most of my objects from the database, they have their attributes initialized with the values of the database and collections are Lazy loaded. The problem comes with an entity called Business which is loaded as a JavassistLaziInitializer using method find() from EntityManager.

If I execute a get or set method, they use the proxy and give me the values I need, but when I use @Valid and validation annotaions, as the real values are NULL (column values, not collections), I have validation errors like @NotNull.

I was hoping if somebody knows a method to get the columns filled with the JavassistLazyInitializer proxy values, or a method to get the proxy itself.

Note that this behaviour, as I have concerned is not a bug on hibernate because it has been reported several times as a bug but developers advices that is a normal behaviour of hibernate that happend in certain conditions.

Was it helpful?

Solution

I use a 'deproxy()' and a couple of other helper functions, for (as you say) certain kinds of code.

This makes Spring 'autogrow' path binding work, it's necessary for checking actual types when loading possibly subclassed entities thru Hibernate, and for various other amusing corner cases where proxying causes things to break.

public class HbUtils {

    public static <T>  T deproxy (T obj) {
        if (obj == null)
            return obj;
        if (obj instanceof HibernateProxy) {
            // Unwrap Proxy;
            //      -- loading, if necessary.
            HibernateProxy proxy = (HibernateProxy) obj;
            LazyInitializer li = proxy.getHibernateLazyInitializer();
            return (T)  li.getImplementation();
        } 
        return obj;
    }


    public static boolean isProxy (Object obj) {
        if (obj instanceof HibernateProxy)
            return true;
        return false;
    }

    // ----------------------------------------------------------------------------------


    public static boolean isEqual (Object o1, Object o2) {
        if (o1 == o2)
            return true;
        if (o1 == null || o2 == null) 
            return false;
        Object d1 = deproxy(o1);
        Object d2 = deproxy(o2);
        if (d1 == d2 || d1.equals(d2))
            return true;
        return false;
    }

    public static boolean notEqual (Object o1, Object o2) {
        return ! isEqual( o1, o2);
    }

    // ----------------------------------------------------------------------------------

    public static boolean isSame (Object o1, Object o2) {
        if (o1 == o2)
            return true;
        if (o1 == null || o2 == null) 
            return false;
        Object d1 = deproxy(o1);
        Object d2 = deproxy(o2);
        if (d1 == d2)
            return true;
        return false;
    }

    public static boolean notSame (Object o1, Object o2) {
        return ! isSame( o1, o2);
    }



    // ----------------------------------------------------------------------------------

    public static Class getClassWithoutInitializingProxy (Object obj) {
        if (obj instanceof HibernateProxy) {
            HibernateProxy proxy = (HibernateProxy) obj;
            LazyInitializer li = proxy.getHibernateLazyInitializer();
            return li.getPersistentClass();
        } 
        // Not a Proxy.
        return obj.getClass();
    }

}

I use a class like this in every major Hibernate project. PS: This isn't my only Hibernate helper -- I have one for generically getting IDs and checking if entities are New/Existent.

Hope this helps!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top