休眠多对一注释外键 javax.el.E​​LException

Posted

技术标签:

【中文标题】休眠多对一注释外键 javax.el.E​​LException【英文标题】:Hibernate many to one annotation foreign key javax.el.ELException 【发布时间】:2016-11-03 07:40:11 【问题描述】:

我有 2 个具有多对一映射的类:

购物车类:

@Entity
@Table(name = "Cart")
public class Cart 

 @Id
 @Column(name = "ID", nullable = false)
 private String id;

 @ManyToOne(fetch = FetchType.LAZY, targetEntity = User.class)
 @JoinColumn(name = "UserID", referencedColumnName = "ID")
 private User user;

用户类别:

@Entity
@Table(name = "User")
public class User 
 @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
 private Set<Cart> carts = new HashSet<Cart>();

当我从购物车对象中获取外键时,它总是返回错误。像下面的代码:

<c:set var="cart" value='<%=CartDAO.getCart("CT00001")%>' />
<c:out value="$cart.user.id" />

还有我的问题:

SEVERE: Servlet.service() for servlet [jsp] in context with path [/mavenHibernate] threw exception [javax.el.ELException: Error reading 'id' on type model.User_$$_jvst39a_3] with root cause
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:147)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:260)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
at model.User_$$_jvst39a_3.getId(User_$$_jvst39a_3.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:94)
at org.apache.jasper.el.JasperELResolver.getValue(JasperELResolver.java:110)
at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:184)
at org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(PageContextImpl.java:944)
at org.apache.jsp.test_jsp._jspx_meth_c_005fout_005f0(test_jsp.java:209)
at org.apache.jsp.test_jsp._jspService(test_jsp.java:176)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:443)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:385)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:329)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:784)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:802)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1452)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)

当我使用休眠 xml 映射时,它没有发生。请帮我解决这个问题。我找不到任何解决方案。

编辑: 这是xml映射版本:

购物车.hbm.xml:

<hibernate-mapping>
 <class name="model.Cart" table="CART">
    <id name="id" type="java.lang.String">
        <column name="ID" />
        <generator class="assigned" />
    </id>
    <many-to-one name="user" class="model.User" fetch="select">
        <column name="USERID" />
    </many-to-one>
    <set name="cartItems" table="CARTITEM" inverse="true" lazy="true" fetch="select">
        <key>
            <column name="CARTID" />
        </key>
        <one-to-many class="model.CartItem" />
    </set>
 </class>
</hibernate-mapping>

用户.hbm.xml:

<hibernate-mapping>
 <class name="model.User" table="USER">
    <id name="id" type="java.lang.String">
        <column name="ID" />
        <generator class="assigned" />
    </id>
    <set name="carts" table="CART" inverse="true" lazy="true" fetch="select">
        <key>
            <column name="USERID" />
        </key>
        <one-to-many class="model.Cart" />
    </set>
 </class>
</hibernate-mapping>

他们创建相同的查询:

xml查询:

 Hibernate: select cart0_.ID as ID1_2_, cart0_.USERID as USERID2_2_, cart0_.DATEADD as DATEADD3_2_, cart0_.ACTIVE as ACTIVE4_2_ from CART cart0_ where cart0_.ID=?

注解查询:

 Hibernate: select cart0_.ID as ID1_2_, cart0_.Active as Active2_2_, cart0_.DateAdd as DateAdd3_2_, cart0_.UserID as UserID4_2_ from Cart cart0_ where cart0_.ID=?

为什么注解查询会抛出异常而xml查询不会?我仍然不知道是什么导致了这个问题。

已编辑 2:只是想为此找到解决方案。

已编辑 3:仍在寻找解决方案。

【问题讨论】:

【参考方案1】:

您已将@ManyToOne 关系设置为FetchType.LAZY。将其更改为 EAGER,或者更好的是,完全删除 fetch 属性,因为 ManyToOne 默认为 EAGER。

【讨论】:

这就是我想要解决的问题。当我使用 FetchType.Eager 时,它会不必要地加载用户的所有字段。特别是当我只想使用 userid 时,它存储在 UserId 字段中。但我无法使用 cart.user.id 访问它。 用了就没有必要了。但是如果你仍然想保持它 LAZY,你必须在调用 user.getId 之前发出 cart.getUser 以便休眠加载该对象,然后你可以访问它的字段。 我发布了更多信息。希望这可以使它更清楚。感谢您的帮助。

以上是关于休眠多对一注释外键 javax.el.E​​LException的主要内容,如果未能解决你的问题,请参考以下文章

休眠延迟加载不适用于多对一映射

可空多对一的休眠默认连接

外键长的多对一迁移失败

Hibernate,关系映射的多对一单向关联多对一双向关联一对一主键关联一对一外键关联多对多关系关联

子表,父表;一对多,多对一;主键,外键梳理。

Hibernate多对一更新外键为null