I have a many-to-many relationship between classes/tables T1 and T2, and the relationship is represented by a class/table R:
T1 <= R => T2
I created one row in table t1, two rows in table t2, and two rows in table r to link them.
t1 (id = 1) <-- r (id1 = 1, id2 = 1) --> t2 (id = 1)
t1 (id = 2) <-- r (id1 = 1, id2 = 2) --> t2 (id = 2)
I load a T1 object in one session, close that session, and reassociate the T1 object with the new session by calling session.lock(). I expect that after the reassociation, I can navigate from T1 to R and then to two T2 objects; in addition, because T1 is reassociated to the new session, I expect any R or T2 objects attached to T1 will also be reassociated to the new session too. I wrote a Test class to check that by calling session.contains().
When I reassociate once, I get the expected behavior. However, if I close the session and reassociate the T1 object with yet another new session, the T2 objects are no longer associated with that session! How can a second lock() call no work while the first lock() call works?
Thanks so much for your help!
Sample output:
run 1
t1 with id 1 reassociated with new session
Hibernate: select r0_.id1 as id1__, r0_.id as id__, r0_.id as id1_, r0_.id1 as id11_, r0_.id2 as id21_, t21_.id as id0_, t21_.name as name0_ from r r0_ left outer join t2 t21_ on r0_.id2=t21_.id where r0_.id1=?
r with id 1 attached to session: true
t2 with id 1 attached to session: true
r with id 2 attached to session: true
t2 with id 2 attached to session: true
run 2
t1 with id 1 reassociated with new session
r with id 1 attached to session: true
t2 with id 1 attached to session: false
r with id 2 attached to session: true
t2 with id 2 attached to session: false
Hibernate version:
2.1.8
Mapping documents:
Code:
<class name="T1" table="t1">
<id name="id">
<generator class="identity"/>
</id>
<property name="name"/>
<set name="r" lazy="true" inverse="true" cascade="all-delete-orphan">
<key column="id1"/>
<one-to-many class="R"/>
</set>
</class>
<class name="T2" table="t2">
<id name="id">
<generator class="identity"/>
</id>
<property name="name"/>
<set name="r" lazy="true" inverse="true" cascade="all-delete-orphan">
<key column="id2"/>
<one-to-many class="R"/>
</set>
</class>
<class name="R" table="r">
<id name="id">
<generator class="identity"/>
</id>
<many-to-one name="t1" class="T1" column="id1"
not-null="true"/>
<many-to-one name="t2" class="T2" column="id2"
not-null="true"/>
</class>
Code between sessionFactory.openSession() and session.close():Code:
public class T1 {
private Integer id;
private String name;
private Set r;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getR() {
return r;
}
public void setR(Set r) {
this.r = r;
}
}
public class T2 {
private Integer id;
private String name;
private Set r;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getR() {
return r;
}
public void setR(Set r) {
this.r = r;
}
}
public class R {
private Integer id;
private T1 t1;
private T2 t2;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public T1 getT1() {
return t1;
}
public void setT1(T1 t1) {
this.t1 = t1;
}
public T2 getT2() {
return t2;
}
public void setT2(T2 t2) {
this.t2 = t2;
}
}
public class Test {
private static SessionFactory sessionFactory;
private static void init() throws Exception {
Configuration cfg = new Configuration();
sessionFactory = cfg.configure().buildSessionFactory();
}
private static Session getSession() throws Exception {
return sessionFactory.openSession();
}
public static void main(String[] args) throws Exception {
init();
Session session = getSession();
T1 t1 = (T1) session.load(T1.class, new Integer(1));
session.close();
System.out.println("run 1");
test(t1);
System.out.println("run 2");
test(t1);
}
private static void test(T1 t1) throws Exception {
Session session = getSession();
session.lock(t1, LockMode.NONE);
System.out.println("t1 with id " +
t1.getId() + " reassociated with new session");
Iterator it = t1.getR().iterator();
while (it.hasNext()) {
R r = (R) it.next();
System.out.println("r with id " +
r.getId() + " attached to session: " +
session.contains(r));
T2 t2 = r.getT2();
System.out.println("t2 with id " +
t2.getId() + " attached to session: " +
session.contains(t2));
}
session.close();
}
}
Full stack trace of any exception that occurs:
(Not applicable)
Name and version of the database you are using:
MySQL 4.0.18
The generated SQL (show_sql=true):
(Not applicable)
Debug level Hibernate log excerpt:
(Not applicable)