-->
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.  [ 1 post ] 
Author Message
 Post subject: Discrepancy between "this" and proxy
PostPosted: Thu Mar 15, 2007 11:44 am 
Newbie

Joined: Tue Mar 13, 2007 2:06 pm
Posts: 3
While trying to remove a child from its parent's collection of children, if the collection contains proxies to the children (rather than the children themselves), the child cannot remove itself.

Code:
// Following code won't work because "this" != proxy.
parent.getChildren().remove(this);


In the code provided below, the equals and hashCode methods have not been overridden since we don't use detached objects. The Object.equals() is being used to compare instances of the Child class. If all loads are performed using session.get(...), then this works correctly since proxies won't come into play. However, we would like to use session.load(...) specifically for the lazy-load benefit.

Questions:
1. What is the suggested way to handle removing a child from its parent's collection of child proxies without tricking Hibernate into not using proxies?

2. Should the CGLIB-generated proxy override the equals() method such that proxy.equals(POJO) is true?

Hibernate version:
3.2.2

Mapping documents:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="hibernate.example.Child" table="child">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <many-to-one name="parent" column="parent_id" class="hibernate.example.Parent" />
    </class>
</hibernate-mapping>


Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="hibernate.example.Parent" table="parent">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
      <set name="children" cascade="save-update">
         <key column="parent_id" />         
         <one-to-many class="hibernate.example.Child" />
      </set>
    </class>
</hibernate-mapping>


Code between sessionFactory.openSession() and session.close():

( POJOs )
Code:
package hibernate.example;

import java.util.HashSet;
import java.util.Set;

public class Parent {
    private long id;
    private Set<Child> children = new HashSet<Child>();
   
    public long getId() {
        return id;
    }
   
    public void setId(long id) {
        this.id = id;
    }

    public Set<Child> getChildren() {
        return children;
    }
   
    public void setChildren(Set<Child> children) {
        this.children = children;
    }
       
    public void addChild(Child newChild) {
        newChild.setParent(this);
        this.children.add(newChild);
    }
}


Code:
package hibernate.example;

public class Child {
    private long id;
    private Parent parent;

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent newParent) {
        if (this.parent != null && !(this.parent.equals(newParent))) {
            // bug: if the collection of children has a reference to the proxy,
            // this call will not succeed (since this != proxy)
            this.parent.getChildren().remove(this);
        }
       
        this.parent = newParent;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }
}


( JUnit test )
Code:
    @Test
    public void removeChild() throws Exception {
        long childId = persistChild();
        session.beginTransaction();
       
        Child childProxy = (Child) session.load(Child.class, childId);
       
        Parent oldParent = childProxy.getParent();
        Parent newParent = new Parent();
       
        assertTrue(oldParent.getChildren().contains(childProxy));
       
        childProxy.setParent(newParent);
        assertFalse(oldParent.getChildren().contains(childProxy));

        session.save(newParent);
        session.getTransaction().commit();
    }

    private long persistChild() {
        session.beginTransaction();
       
        Child child = new Child();
        Parent parent = new Parent();
        parent.addChild(child);
        session.save(parent);
       
        session.getTransaction().commit();
       
        // reopen the session to load new objects/proxies into the session
        session.close();
        session = HibernateUtil.getSessionFactory().openSession();
       
        return child.getId();
    }


Full stack trace of any exception that occurs:
No exception occurs; test fails.

Name and version of the database you are using:
MySQL 5.0.x

The generated SQL (show_sql=true):
Quote:
10:05:28,686 DEBUG SQL:393 - insert into parent values ( )
Hibernate: insert into parent values ( )
10:05:28,733 DEBUG SQL:393 - insert into child (parent_id) values (?)
Hibernate: insert into child (parent_id) values (?)
10:05:28,749 DEBUG SQL:393 - update child set parent_id=? where id=?
Hibernate: update child set parent_id=? where id=?
10:05:28,796 DEBUG SQL:393 - select child0_.id as id9_0_, child0_.parent_id as parent2_9_0_ from child child0_ where child0_.id=?
Hibernate: select child0_.id as id9_0_, child0_.parent_id as parent2_9_0_ from child child0_ where child0_.id=?
10:05:28,796 DEBUG SQL:393 - select parent0_.id as id8_0_ from parent parent0_ where parent0_.id=?
Hibernate: select parent0_.id as id8_0_ from parent parent0_ where parent0_.id=?
10:05:28,811 DEBUG SQL:393 - select children0_.parent_id as parent2_1_, children0_.id as id1_, children0_.id as id9_0_, children0_.parent_id as parent2_9_0_ from child children0_ where children0_.parent_id=?
Hibernate: select children0_.parent_id as parent2_1_, children0_.id as id1_, children0_.id as id9_0_, children0_.parent_id as parent2_9_0_ from child children0_ where children0_.parent_id=?


Debug level Hibernate log excerpt:
88k log available on request
    Code:


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

    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.