javax.el.E​​LException:无法将类型为Protocol的Protocol @ 7ebc9002转换为Protocol $$ EnhancerByCGLIB $$ 22af7fa3(延迟加载)

时间:2018-01-11 09:54:21

标签: spring converter lazy-loading jsf-1.2 hibernate3

我很难让hibernate 3.1延迟加载与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)

我读到hibernate将根据需要替换延迟加载代理,但似乎无法在JSF转换器调用上工作。

请注意,协议绑定到视图中的单选按钮

你知道如何解决这个问题吗?我找不到与我有同样问题的人。

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>

观点:

<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);
    }
}

1 个答案:

答案 0 :(得分:0)

我想(最后)如何解决这个问题。我不确定这是否是正确的方法,但它确实有效。

我添加了这段代码:

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;
}

我在我的转换器中这样称呼它:

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

}

而不是:

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

顺便说一下,当我认为$$ EnhancedByCGLIB $$必然意味着一个hibernate代理时,我犯了一个错误。我在其他地方读到它是一个库,例如也可以被Spring依赖注入使用。只是为了让你知道。

我希望这会帮助剩下的少数jsf 1.2 / hibernate 3.1用户。我应该自己投票吗?