0

I have 2 classes with many to one mapping:

Cart class:

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

User class:

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

The problem when i get foreign key from cart object, it always return error. Like the following code:

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

And my problem:

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)

It didn't happen when i use hibernate xml mapping. Please help me fix this. I can't find any solution.

Edited: And this is xml mapping version:

Cart.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>

User.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>

They create same queries:

xml query:

 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=?

annotation query:

 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=?

Why did annotation query throw exception and xml query not? I still don't know what cause this problem.

Edited 2: just want to find a solution for this.

Edited 3: still wandering for a solution.

ChartFlow
  • 1
  • 1

1 Answers1

1

You have set your @ManyToOne relation to be FetchType.LAZY. Change it to EAGER or, better yet, remove fetch property entirely because ManyToOne is EAGER by default.

Community
  • 1
  • 1
veljkost
  • 1,408
  • 18
  • 21
  • That's what i want to solve. When i use FetchType.Eager, it will load all fields of user unnecessarily. Especially when i only want to use userid, it stored in UserId fields. But I can't access it by using cart.user.id. – ChartFlow Nov 03 '16 at 11:24
  • It's not unnecessary if you use it. But if you still want to keep it LAZY, you have to issue cart.getUser prior to calling user.getId so that hibernate loads that object, and then you can access its fields. – veljkost Nov 03 '16 at 12:03
  • I posted more information. Hope this can make it clearer. Thank for your help. – ChartFlow Nov 03 '16 at 12:52