-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 
Author Message
 Post subject: Many-to-Many Mapping issue
PostPosted: Wed Nov 11, 2009 11:42 am 
Newbie

Joined: Wed Nov 11, 2009 10:58 am
Posts: 3
Hi,

I have an issue while mapping many-to-many or one-to-many collection using non unique column of one table with the other.(Code of Tables,java and hbm files are mentioned below).

In jsp when I try accessing the collection(example department.employees.size()) its throwing below exception.
When lazy is true for the collection set in hbm
Code:
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.entity.Department.employees, no session or session was closed

When lazy is false for the collection set in hbm
Code:
org.hibernate.HibernateException: collection is not associated with any session
   at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:449)

I am even using the org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor in the dispatcher setting my singleSession to true and flushModeName to FLUSH_AUTO.

I tried searching in the Internet but haven't got any solution for last three days. I would really appreciate if you can provide a solution.

Regards,
Ravi

The tables are
Department
Code:
CREATE TABLE DEPARTMENT
(
  ID           VARCHAR2(30 BYTE),NAME         VARCHAR2(30 BYTE),NON_UNIQUE_ID  VARCHAR2(30 BYTE)
)

Employee
Code:
CREATE TABLE EMPLOYEE
(
  ID    VARCHAR2(30 BYTE),NAME  VARCHAR2(30 BYTE)
)

Department_employee_rel
Code:
CREATE TABLE DEPARTMENT_EMPLOYEE_REL
(
  NON_UNIQUE_ID  VARCHAR2(30 BYTE),
  EMPLOYEE_ID    VARCHAR2(30 BYTE)
)


The java entities are as below
Department
Code:
package com.entity;
import java.io.Serializable;
import java.util.Set;
public class Department implements Serializable {
   static final long serialVersionUID = -1L; private String id; private String name; private String nonUniqueId;
   private Set<Employee> employees;   
   public Set<Employee> getEmployees() {
      return employees;
   }
   public void setEmployees(Set<Employee> employees) {
      this.employees = employees;
   }
   public String getId() {
      return id;
   }
   public void setId(String id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getNonUniqueId() {
      return nonUniqueId;
   }
   public void setNonUniqueId(String nonUniqueId) {
      this.nonUniqueId= nonUniqueId;
   }
}

Employee
Code:
package com.entity;
import java.io.Serializable;
public class Employee implements Serializable {   
   private static final long serialVersionUID = 1L;
   private String id; private String name;
   public String getId() {
      return id;
   }
   public void setId(String id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}


The department hbm file contains the below code
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
   <hibernate-mapping default-cascade="none" default-lazy="true" package="com.entity">   
      <class name="Department"  table="DEPARTMENT" >
         <cache usage="transactional" />
         <id name="id" column="ID" />             
         <property name="nonUniqueId" column="NON_UNIQUE_ID" />          
         <property name="name" column="NAME" />         
         <set name="employees"  table="department_employee_rel">
                              <key column="department_id" property-ref="nonUniqueId"/>
                         <many-to-many column="employee_id" class="Employee" unique="true" />
                         </set>                  
      </class>      
</hibernate-mapping>

Employee hbm
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
   <hibernate-mapping default-cascade="none" default-lazy="true" package="com.entity">   
      <class name="Employee"  table="employee" >
         <cache usage="transactional" />
         <id name="id" column="ID" />          
         <property name="name" column="NAME" />
      </class>      
</hibernate-mapping>


Top
 Profile  
 
 Post subject: Re: Many-to-Many Mapping issue
PostPosted: Wed Nov 11, 2009 6:28 pm 
Newbie

Joined: Wed Nov 11, 2009 5:54 pm
Posts: 2
From the error message it seems like you are not calling the method inside an open hibernate session, cross check with your code and ensure that code to ensure that you have open a session and make sure it still open by the time you call your mehod and close it after. Like below

    openSession();
    //your code
    closeSession();


Top
 Profile  
 
 Post subject: Re: Many-to-Many Mapping issue
PostPosted: Wed Nov 11, 2009 11:43 pm 
Newbie

Joined: Wed Nov 11, 2009 10:58 am
Posts: 3
wycleflo wrote:
From the error message it seems like you are not calling the method inside an open hibernate session, cross check with your code and ensure that code to ensure that you have open a session and make sure it still open by the time you call your mehod and close it after. Like below

    openSession();
    //your code
    closeSession();


Thanks for the reply.

But the same code works fine if the NON_UNIQUE_COLUMN i.e. mapped with the department_employee_rel table contains only Unique values.


Top
 Profile  
 
 Post subject: Re: Many-to-Many Mapping issue
PostPosted: Thu Nov 12, 2009 3:34 pm 
Newbie

Joined: Mon Feb 23, 2009 11:16 am
Posts: 17
By default collections are Lazy-Loaded. This means that hibernate will not actually populate the collection until you try to access it, up until that point the collection is a proxy collection class that's really just a placeholder.

If you access this placeholder outside of a session then hibernate will have no way to reach the DB and load up the collections, thus the error you are receiving.

A quick fix is to set "default-lazy=false" and it should work without a problem. This way when your object gets loaded the whole collection gets populated right away (while you're still in a session). Of course this will make your program run slower if there are lots of cases where you wouldn't had accessed the collection, but such is the price to pay for not staying in a session.

NOTE: I re-read your post and realize you have played with the lazy-init settings. From my experience you would have to set both of the mapped classes to lazy=false as well as the actual set you're mapping to lazy=false since collections and such also get lazy loaded when possible.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 4 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.