-->
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.  [ 2 posts ] 
Author Message
 Post subject: delete orphan and bi-directional one-to-many association
PostPosted: Mon Mar 19, 2007 6:20 am 
Newbie

Joined: Sat Aug 12, 2006 1:20 am
Posts: 7
I have one-to-many set based bi-directional association. See relavant code below. The cascade setting is all, delete-orphan. Now if a child is removed from collection of one entity but added to the collection of another entity, I wouldn't expect it to be deleted. ( Essentially the cascade induced delete gets offset by another cascade induced update ). However, the entity removed from the collection gets deleted in spite of being referenced from the collection of another entity. I've attached some excerpt from the debug logs. If you notice, the pretty printer logs indicate that SampleGroup#3 is being referenced by SampleGroup#1, but in spite of this SampleGroup#3 is being deleted.

Am i missing something or is this a bug ? If this is indeed a bug, does anyone know of a workaround ?

Thanks,
Radhakrishnan

3.2.2

Code:
@Entity
public class SampleGroup implements TreeNode {
    @Id @GeneratedValue
    private Long id;
   
    @ManyToOne(optional=true)
    private SampleGroup myParent;
   
    @OneToMany(mappedBy="myParent")
    @Cascade({CascadeType.ALL,CascadeType.DELETE_ORPHAN})
    private Set<SampleGroup> includesGroups = new LinkedHashSet<SampleGroup>();

    @Embedded
    private TreeNodeInfo treeNodeInfo = new TreeNodeInfo();
   
    private String treeName;
   
    private String groupName;
   
   
   
    public SampleGroup() {
        super();
        treeName = " Simple Group ";
    }

    public TreeNodeInfo getNodeInfo() {
        return treeNodeInfo;
    }

    public TreeNode getParent() {
        return myParent;
    }

    public String getTreeName() {
        return treeName;
    }

   
    /**
     * @return the myParent
     */
    public SampleGroup getMyParent() {
        return myParent;
    }

    /**
     * @param myParent the myParent to set
     */
    public void setMyParent(SampleGroup myParent) {
        this.myParent = myParent;
    }

    /**
     * @return the treeNodeInfo
     */
    public TreeNodeInfo getTreeNodeInfo() {
        return treeNodeInfo;
    }

    /**
     * @param treeNodeInfo the treeNodeInfo to set
     */
    public void setTreeNodeInfo(TreeNodeInfo treeNodeInfo) {
        this.treeNodeInfo = treeNodeInfo;
    }

    /**
     * @return the groupName
     */
    public String getGroupName() {
        return groupName;
    }

    /**
     * @param groupName the groupName to set
     */
    public void setGroupName(String groupName) {
        this.groupName = groupName;
    }

    /**
     * @param treeName the treeName to set
     */
    public void setTreeName(String treeName) {
        this.treeName = treeName;
    }

    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
   
    public void includeGroup(SampleGroup group) {
        group.setMyParent(this);
        includesGroups.add(group);
    }
   
    public void excludeGroup(SampleGroup group) {
        if (this.equals(group.getMyParent())) {
            group.setMyParent(null);
            includesGroups.remove(group);
        }       
    }
   
    public boolean includesGroup(SampleGroup group) {
        return includesGroups.contains(group);
    }
   
    private static MessageFormat messageFormat = new MessageFormat("tree=''{0}'', group=''{1}'', id={2}, {3} ");
   
   
    @Override
    public String toString() {
        return messageFormat.format(new Object[]{treeName,groupName,id,treeNodeInfo});
    }


Code:
        SampleGroup group1 = new SampleGroup();
        group1.setGroupName("group 1");
       
        SampleGroup group2 = new SampleGroup();
        group2.setGroupName("group 2");
       
        SampleGroup group3 = new SampleGroup();
        group3.setGroupName("group 3");
       
        group1.includeGroup(group2);
        group2.includeGroup(group3);
        sampleGroupRepository.save(group1);
        assertNotNull(group1.getId());
        assertNotNull(group2.getId());
        assertNotNull(group3.getId());
       
       
        //Flushes the session and clears it.
        flushAndClear();

        SampleGroup _1_reloaded = sampleGroupRepository.findById( group1.getId() );
        SampleGroup _2_reloaded = sampleGroupRepository.findById( group2.getId() );
        SampleGroup _3_reloaded = sampleGroupRepository.findById( group3.getId() );
       
        assertNotNull( _1_reloaded );
        assertNotNull( _2_reloaded );
        assertNotNull( _3_reloaded );
       
        assertTrue( _1_reloaded.includesGroup(_2_reloaded) );
        assertTrue( _2_reloaded.includesGroup(_3_reloaded) );
       
        //Move 3 from 2 to 1.
        _2_reloaded.excludeGroup(_3_reloaded);
        _1_reloaded.includeGroup(_3_reloaded);
       
        assertTrue( _1_reloaded.includesGroup(_2_reloaded) );
        assertTrue( _1_reloaded.includesGroup(_3_reloaded) );
       
        assertFalse( _2_reloaded.includesGroup(_3_reloaded) );

        sampleGroupRepository.update(_1_reloaded);
       
        flushAndClear();
       
        _1_reloaded = sampleGroupRepository.findById( group1.getId() );
        _2_reloaded = sampleGroupRepository.findById( group2.getId() );
        _3_reloaded = sampleGroupRepository.findById( group3.getId() );

        assertNotNull(_3_reloaded);//This fails.
        //assertNotNull(_2_reloaded); //This also fails.




HyperSonic 1.8.0.4


Hibernate: insert into sample_group (id, my_parent, tree_node_info_lft, tree_node_info_rgt, tree_name, group_name) values (null, ?, ?, ?, ?, ?)
Hibernate: call identity()
Hibernate: insert into sample_group (id, my_parent, tree_node_info_lft, tree_node_info_rgt, tree_name, group_name) values (null, ?, ?, ?, ?, ?)
Hibernate: call identity()
Hibernate: insert into sample_group (id, my_parent, tree_node_info_lft, tree_node_info_rgt, tree_name, group_name) values (null, ?, ?, ?, ?, ?)
Hibernate: call identity()
Hibernate: select samplegrou0_.id as id95_1_, samplegrou0_.my_parent as my6_95_1_, samplegrou0_.tree_node_info_lft as tree2_95_1_, samplegrou0_.tree_node_info_rgt as tree3_95_1_, samplegrou0_.tree_name as tree4_95_1_, samplegrou0_.group_name as group5_95_1_, samplegrou1_.id as id95_0_, samplegrou1_.my_parent as my6_95_0_, samplegrou1_.tree_node_info_lft as tree2_95_0_, samplegrou1_.tree_node_info_rgt as tree3_95_0_, samplegrou1_.tree_name as tree4_95_0_, samplegrou1_.group_name as group5_95_0_ from sample_group samplegrou0_ left outer join sample_group samplegrou1_ on samplegrou0_.my_parent=samplegrou1_.id where samplegrou0_.id=?
Hibernate: select samplegrou0_.id as id95_1_, samplegrou0_.my_parent as my6_95_1_, samplegrou0_.tree_node_info_lft as tree2_95_1_, samplegrou0_.tree_node_info_rgt as tree3_95_1_, samplegrou0_.tree_name as tree4_95_1_, samplegrou0_.group_name as group5_95_1_, samplegrou1_.id as id95_0_, samplegrou1_.my_parent as my6_95_0_, samplegrou1_.tree_node_info_lft as tree2_95_0_, samplegrou1_.tree_node_info_rgt as tree3_95_0_, samplegrou1_.tree_name as tree4_95_0_, samplegrou1_.group_name as group5_95_0_ from sample_group samplegrou0_ left outer join sample_group samplegrou1_ on samplegrou0_.my_parent=samplegrou1_.id where samplegrou0_.id=?
Hibernate: select samplegrou0_.id as id95_1_, samplegrou0_.my_parent as my6_95_1_, samplegrou0_.tree_node_info_lft as tree2_95_1_, samplegrou0_.tree_node_info_rgt as tree3_95_1_, samplegrou0_.tree_name as tree4_95_1_, samplegrou0_.group_name as group5_95_1_, samplegrou1_.id as id95_0_, samplegrou1_.my_parent as my6_95_0_, samplegrou1_.tree_node_info_lft as tree2_95_0_, samplegrou1_.tree_node_info_rgt as tree3_95_0_, samplegrou1_.tree_name as tree4_95_0_, samplegrou1_.group_name as group5_95_0_ from sample_group samplegrou0_ left outer join sample_group samplegrou1_ on samplegrou0_.my_parent=samplegrou1_.id where samplegrou0_.id=?
Hibernate: select includesgr0_.my_parent as my6_1_, includesgr0_.id as id1_, includesgr0_.id as id95_0_, includesgr0_.my_parent as my6_95_0_, includesgr0_.tree_node_info_lft as tree2_95_0_, includesgr0_.tree_node_info_rgt as tree3_95_0_, includesgr0_.tree_name as tree4_95_0_, includesgr0_.group_name as group5_95_0_ from sample_group includesgr0_ where includesgr0_.my_parent in (?, ?, ?)
Hibernate: delete from sample_group where id=?
Hibernate: select samplegrou0_.id as id95_1_, samplegrou0_.my_parent as my6_95_1_, samplegrou0_.tree_node_info_lft as tree2_95_1_, samplegrou0_.tree_node_info_rgt as tree3_95_1_, samplegrou0_.tree_name as tree4_95_1_, samplegrou0_.group_name as group5_95_1_, samplegrou1_.id as id95_0_, samplegrou1_.my_parent as my6_95_0_, samplegrou1_.tree_node_info_lft as tree2_95_0_, samplegrou1_.tree_node_info_rgt as tree3_95_0_, samplegrou1_.tree_name as tree4_95_0_, samplegrou1_.group_name as group5_95_0_ from sample_group samplegrou0_ left outer join sample_group samplegrou1_ on samplegrou0_.my_parent=samplegrou1_.id where samplegrou0_.id=?
Hibernate: select samplegrou0_.id as id95_1_, samplegrou0_.my_parent as my6_95_1_, samplegrou0_.tree_node_info_lft as tree2_95_1_, samplegrou0_.tree_node_info_rgt as tree3_95_1_, samplegrou0_.tree_name as tree4_95_1_, samplegrou0_.group_name as group5_95_1_, samplegrou1_.id as id95_0_, samplegrou1_.my_parent as my6_95_0_, samplegrou1_.tree_node_info_lft as tree2_95_0_, samplegrou1_.tree_node_info_rgt as tree3_95_0_, samplegrou1_.tree_name as tree4_95_0_, samplegrou1_.group_name as group5_95_0_ from sample_group samplegrou0_ left outer join sample_group samplegrou1_ on samplegrou0_.my_parent=samplegrou1_.id where samplegrou0_.id=?
Hibernate: select samplegrou0_.id as id95_1_, samplegrou0_.my_parent as my6_95_1_, samplegrou0_.tree_node_info_lft as tree2_95_1_, samplegrou0_.tree_node_info_rgt as tree3_95_1_, samplegrou0_.tree_name as tree4_95_1_, samplegrou0_.group_name as group5_95_1_, samplegrou1_.id as id95_0_, samplegrou1_.my_parent as my6_95_0_, samplegrou1_.tree_node_info_lft as tree2_95_0_, samplegrou1_.tree_node_info_rgt as tree3_95_0_, samplegrou1_.tree_name as tree4_95_0_, samplegrou1_.group_name as group5_95_0_ from sample_group samplegrou0_ left outer join sample_group samplegrou1_ on samplegrou0_.my_parent=samplegrou1_.id where samplegrou0_.id=?



DEBUG org.hibernate.event.def.AbstractFlushingEventListener : Scheduling collection removes/(re)creates/updates
DEBUG org.hibernate.event.def.AbstractFlushingEventListener : Flushed: 0 insertions, 0 updates, 1 deletions to 3 objects
DEBUG org.hibernate.event.def.AbstractFlushingEventListener : Flushed: 0 (re)creations, 2 updates, 1 removals to 3 collections
DEBUG org.hibernate.pretty.Printer : listing entities:
DEBUG org.hibernate.pretty.Printer : tavant.twms.infra.SampleGroup{treeNodeInfo=component[lft,rgt]{lft=1, rgt=2}, treeName= Simple Group , groupName=group 1, includesGroups=[tavant.twms.infra.SampleGroup#2, tavant.twms.infra.SampleGroup#3], myParent=null, id=1}
DEBUG org.hibernate.pretty.Printer : tavant.twms.infra.SampleGroup{treeNodeInfo=component[lft,rgt]{lft=1, rgt=2}, treeName= Simple Group , groupName=group 2, includesGroups=[], myParent=tavant.twms.infra.SampleGroup#1, id=2}
DEBUG org.hibernate.pretty.Printer : tavant.twms.infra.SampleGroup{treeNodeInfo=component[lft,rgt]{lft=1, rgt=2}, treeName= Simple Group , groupName=group 3, includesGroups=[], myParent=tavant.twms.infra.SampleGroup#1, id=3}
DEBUG org.hibernate.event.def.AbstractFlushingEventListener : executing flush
DEBUG org.hibernate.jdbc.ConnectionManager : registering flush begin
DEBUG org.hibernate.persister.entity.AbstractEntityPersister : Deleting entity: [tavant.twms.infra.SampleGroup#3]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Mar 19, 2007 3:59 pm 
Newbie

Joined: Sat Aug 12, 2006 1:20 am
Posts: 7
Just to be clear, quoting the environment details again.

Hibernate version : 3.2.2
Database : HSQL 1.8.0.4

Can someone shed some light on this problem ?

Thanks,
Radhakrishnan


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 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.