简体   繁体   中英

javax.el.ELException: Cannot convert Protocol@7ebc9002 of type class Protocol to class Protocol$$EnhancerByCGLIB$$22af7fa3 (lazy loadding)

I struggle to make hibernate 3.1 lazy loading working with JSF 1.2

Caused by: javax.el.ELException: Cannot convert foo.bar.Protocol@7ebc9002 of type class foo.bar.Protocol to class foo.bar.Protocol$$EnhancerByCGLIB$$22af7fa3
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:438)
at org.apache.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:46)
at com.sun.faces.renderkit.html_basic.RadioRenderer.renderOption(RadioRenderer.java:87)
at com.sun.faces.renderkit.html_basic.SelectManyCheckboxListRenderer.encodeEnd(SelectManyCheckboxListRenderer.java:146)

I read that hibernate will replace the lazy loading proxy on demand, but it seems to do not work on JSF converter call.

Note that Protocols are bound to radio buttons in the view

Do you know how to workaround this ? I can't find someone who have the same issue as me.

applicationContext :

<bean id="protocol" class="foo.bar.Protocol" abstract="false"
    lazy-init="default" autowire="byName" dependency-check="default" scope="session">
    <aop:scoped-proxy />
</bean>

<bean id="protocolConverter" class="foo.bar.ProtocolConverter" abstract="false" 
    lazy-init="default" autowire="byName" dependency-check="default" scope="singleton">
    <property name="protocolDAO" ref="protocolDAO" />
</bean>

view :

<h:selectOneRadio value="#{pingControler.ping.protocol}" converter="#{protocolConverter}">
    <f:selectItems value="#{pingControler.allProtocolsSelectItems}" />
    <a4j:support event="onchange" reRender="foo1,foo2" />
</h:selectOneRadio>

ping :

public class Ping {

    // Fields
    private Integer pingId;
    private Protocol protocol;
    ...

}

pingControler :

private Ping ping;

public void init(ActionEvent event) {
    ping = new Ping();
}

public void save(ActionEvent event) throws Exception {
    if (ping.getPingId() == null) {
        pingPersistent.addPing(ping);
    } else {
        pingPersistent.updatePing(ping);
    }
}

I figured out (finally) how to workaround this. I'm not sure if this is the proper way, but it works.

I added this code :

private static <T> T initializeAndUnproxy(T entity) {
    if (entity == null) {
        throw new NullPointerException("Entity passed for initialization is null");
    }
    Hibernate.initialize(entity);
    if (entity instanceof HibernateProxy) {
        entity = (T) ((HibernateProxy) entity).getHibernateLazyInitializer().getImplementation();
    }
    return entity;
}

And i called it in my Converter like this :

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
    Protocol protocol = protocolDAO.findById(new Integer(value));
    return initializeAndUnproxy(protocol);

}

instead of this :

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String value) {
    return protocolDAO.findById(new Integer(value));
}

By the way, i did a mistake when i though that $$EnhancedByCGLIB$$ necessarily means an hibernate proxy. I read somewhere else that it's a library and could be used by Spring dependency injection too for example. Just to let you know.

I hope this will help the few jsf 1.2 / hibernate 3.1 users remaining. Should i upvote myself ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM