Version 2

    This page explains how to load and store instances that are wrapped with a JDK dynamic proxy.

    First, you need an interface:

    public interface FooInterface {
    
        public Long getId();
        public void setId(Long id);
        public String getBar();
        public void setBar(String bar);
    
    }
    

    Next, a concrete class that implements this interface:

    public class Foo implements FooInterface {
    
        private Long id;
        private String bar;
    
        public Foo() {}
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
    
        public String getBar() {
            return bar;
        }
    
        public void setBar(String bar) {
            this.bar = bar;
        }
    }
    

    A proxy is a class that wraps a concrete instance that implements a given interface. This is a possible proxy:

    public class FooProxy implements InvocationHandler {
    
        Object obj;
    
        public FooProxy(Object obj) {
            this.obj = obj;
        }
    
        public Object invoke(Object proxy, Method m, Object[] args) throws
                Throwable {
            try {
                // Do something on real object
                return m.invoke(obj, args);
            } catch (InvocationTargetException e) {
                throw e.getTargetException();
            } catch (Exception e) {
                throw e;
            }
        }
    
        public static Object newInstance(Object obj, Class[] interfaces) {
            return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                                          interfaces,
                                          new FooProxy(obj));
        }
    }
    

     

    Note that this proxy implementation does nothing, in other words, it does not implement any additional functionality. Every method called on the proxy is directly passed on to a method call on the real object. I also included a factory method.

    Let's map this with Hibernate XML. You map the interface:

    <hibernate-mapping>
    
    <class name="FooInterface"
           table="FOO">
    
        <id name="id" column="FOO_ID" type="long">
        <generator class="native"/>
        </id>
    
        <property name="bar" column="BAR"/>
    
    </class>
    
    </hibernate-mapping>
    

     

    Hibernate will use the getter and setter methods defined by that interface as property accessors. Finally, you need a Hibernate Interceptor to do the proxy magic when loading and storing an object:

    public class FooProxyInterceptor extends EmptyInterceptor {
    
        public String getEntityName(Object object) {
            if (Proxy.isProxyClass(object.getClass()) && object instanceof FooInterface)
                return FooInterface.class.getName();
            return super.getEntityName(object);
        }
    
        public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
            if (entityName.equals(FooInterface.class.getName())) {
                Foo newFoo = new Foo();
                newFoo.setId((Long)id);
                FooInterface foo = (FooInterface)
                      FooProxy.newInstance(newFoo, new Class[]{ FooInterface.class });
                return foo;
            }
            return super.instantiate(entityName, entityMode, id);
        }
    
    }
    

     

    When saving an object, getEntityName() is called. If we would use the default in Hibernate, it would look for a mapping of FooProxy - we don't have that. If a proxied object is saved we instead return the name of the mapped interface.

    When loading an object, a concrete instance of Foo is needed, and it has to be wrapped in a proxy.