0

Form binding (middle object) in ZK 8.0 : what if my ViewModel properties are proxies?

asked 2015-08-21 13:41:31 +0800

MathieuPiette gravatar image MathieuPiette
1567 3

Hi,

I'm using ZK 8.0 and Hibernate in my project. I use MVVM and form binding.

The properties of my ViewModel are Hibernate-managed beans. So they can be proxies. When I use form binding, ZK tries to transform these properties to proxies.

This can be a problem because au proxy can't be tunred into a proxy a second time as both Hibernate and ZK use Javassist.

So I have this exception:

java.lang.RuntimeException: duplicate method: setHandler in com.company.package.MyClass_$$_jvst8dc_10_$$_jvst8dc_1d
    javassist.util.proxy.ProxyFactory.createClass3(ProxyFactory.java:515)
    javassist.util.proxy.ProxyFactory.createClass2(ProxyFactory.java:492)
    javassist.util.proxy.ProxyFactory.createClass1(ProxyFactory.java:428)
    javassist.util.proxy.ProxyFactory.createClass(ProxyFactory.java:400)
    org.zkoss.bind.proxy.ProxyHelper.createProxyIfAny(ProxyHelper.java:88)
    org.zkoss.bind.proxy.BeanProxyHandler.invoke(BeanProxyHandler.java:163)
    com.company.package.MyOtherClass_$$_jvst8dc_1b.getMyClass(MyOtherClass_$$_jvst8dc_1b.java)
    com.company.package.MyOtherClass.equals(MyOtherClass.java:38)
    java.util.ArrayList.indexOf(ArrayList.java:298)
    org.zkoss.zul.ListModelList.indexOf(ListModelList.java:247)
    org.zkoss.zul.ListModelList.fireSelectionEvent(ListModelList.java:458)
    org.zkoss.zul.AbstractListModel.addToSelection(AbstractListModel.java:125)
    org.zkoss.bind.converter.sys.ListboxSelectedItemConverter.coerceToUi(ListboxSelectedItemConverter.java:48)
    org.zkoss.bind.impl.LoadPropertyBindingImpl.load(LoadPropertyBindingImpl.java:74)
    org.zkoss.bind.impl.PropertyBindingHandler.doLoadBinding(PropertyBindingHandler.java:133)
    org.zkoss.bind.impl.PropertyBindingHandler.doLoad(PropertyBindingHandler.java:334)
    org.zkoss.bind.impl.BinderImpl.loadComponentProperties0(BinderImpl.java:2307)
    org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2276)
    org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2281)
    org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2281)
    org.zkoss.bind.impl.BinderImpl.loadComponent0(BinderImpl.java:2281)
    org.zkoss.bind.impl.BinderImpl.loadComponent(BinderImpl.java:2215)
    org.zkoss.bind.BindComposer$BinderKeeper$Loader.load(BindComposer.java:564)
    org.zkoss.bind.BindComposer$BinderKeeper.loadComponentForAllBinders(BindComposer.java:540)
    org.zkoss.bind.BindComposer.doAfterCompose(BindComposer.java:188)
    org.zkoss.zk.ui.impl.UiEngineImpl.doAfterCompose(UiEngineImpl.java:588)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:924)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:870)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:745)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:709)
    org.zkoss.zk.ui.impl.UiEngineImpl.createComponents(UiEngineImpl.java:1124)
    org.zkoss.zk.ui.impl.AbstractExecution.createComponents0(AbstractExecution.java:283)
    org.zkoss.zk.ui.impl.AbstractExecution.createComponents(AbstractExecution.java:271)
    org.zkoss.zul.Include.afterCompose(Include.java:486)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:922)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:870)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:745)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:709)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:916)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:870)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:745)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:709)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:916)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:870)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:745)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:709)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild0(UiEngineImpl.java:916)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:870)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:745)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreateChild(UiEngineImpl.java:814)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate0(UiEngineImpl.java:767)
    org.zkoss.zk.ui.impl.UiEngineImpl.execCreate(UiEngineImpl.java:709)
    org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage0(UiEngineImpl.java:452)
    org.zkoss.zk.ui.impl.UiEngineImpl.execNewPage(UiEngineImpl.java:358)
    org.zkoss.zk.ui.http.DHtmlLayoutServlet.process(DHtmlLayoutServlet.java:217)
    org.zkoss.zk.ui.http.DHtmlLayoutServlet.doGet(DHtmlLayoutServlet.java:136)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

I can't tell Hibernate to use CGlib instead of Javassist, because that feature is deprecated.

I really don't know how I could solve this.

Thank you!

delete flag offensive retag edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2015-09-16 06:56:03 +0800

MathieuPiette gravatar image MathieuPiette
1567 3

I found a workaround to this problem. The thing is you can't have proxies in your ViewModel when using form binding in ZK 8.

So I had to deproxy my Hibernate managed beans, using this utility method:

public <T> T initializeAndUnproxy(T o, boolean initializeAndUnproxyFields) throws IllegalAccessException,
        IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {

    if (o == null) {
        return null;
    }

    Hibernate.initialize(o);
    if (o instanceof HibernateProxy) {
        o = (T)((HibernateProxy)o).getHibernateLazyInitializer().getImplementation();
    }

    if (initializeAndUnproxyFields) {
        for (Method method : o.getClass().getDeclaredMethods()) {
            if (method.getName().startsWith("get") && method.getParameterTypes().length == 0
                    && isHibernateManaged(method.getReturnType())) {
                Object valueOfField = method.invoke(o);
                valueOfField = initializeAndUnproxy(valueOfField, false);
                Method setter = o.getClass().getMethod("s" + method.getName().substring(1),
                        method.getReturnType());
                setter.invoke(o, valueOfField);
            }
        }
    }

    return o;
}

The isHibernateManaged() method looks like this, I couldn't find something better (suggestions welcome):

private boolean isHibernateManaged(Class<?> type) {
    return type.getPackage().getName().equals("com.company.something.beans");
}

In your ViewModel, you use it like this:

    bean = HibernateUtils.initializeAndUnproxy(bean, true);

    Set<OtherBean> unproxiedOtherBeans = new TreeSet<OtherBean>();
    for (OtherBean otherBean : bean.getOtherBeans()) {
        OtherBean unproxiedOtherBean = HibernateUtils.initializeAndUnproxy(otherBean , true);
        unproxiedOtherBeans.add(unproxiedOtherBean );
    }
    bean.getOtherBeans().clear();
    bean.getOtherBeans().addAll(unproxiedOtherBeans);

So your bean property is not a proxy anymore, and its otherBeans collection is not filled with proxies either.

All this could be wrapped in a helper class to reduce the amount of code needed in the ViewModel, but it works.

link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2015-08-21 13:41:31 +0800

Seen: 74 times

Last updated: Sep 16 '15

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More