[hibernate-issues] [Hibernate-JIRA] Created: (HHH-3354) Add entity in one-to-many collection, auto-flush and remove entity does not remove the entity

Pascal Perez (JIRA) noreply at atlassian.com
Tue Jun 24 00:50:18 EDT 2008


Add entity in one-to-many collection, auto-flush and remove entity does not remove the entity
---------------------------------------------------------------------------------------------

                 Key: HHH-3354
                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-3354
             Project: Hibernate3
          Issue Type: Bug
          Components: core
    Affects Versions: 3.2.1
         Environment: Observed on MySQL 5, unit tested on HSQLDB.
            Reporter: Pascal Perez
         Attachments: entities.zip

In plain English:

An Item may have multiple Comment (one-to-many). When adding two comments to an item, auto-flushing, and removing one item, Hibernate loses track of both comments and does not delete the removed comment. The cascading has "delete-orphan".

Hibernate behaves in two different ways depending on whether the removed comment entity holds a reference to the Item or not.

1) if it holds a reference: the Comment entity is not removed. The transaction commits silently.

2) if it does not hold a reference anymore (i.e. comment.item = null): The Comment entity is updated to have it's reference to Item set to NULL, but is not deleted. This creates zombie entities in the DB. This case is highlighted in the unit test below by forcing the relation to be not-null="true" triggering a DB constraint violation upon commit. Otherwise, Hibernate commits silently.

In unit tests (test is parameterized to handle cases 1 and 2):

  @Test
  public void addAutoFlushRemove() throws Exception {
    autoFlushInTheMiddle(false);
  }
  
  @Test
  public void addAutoFlushUnreferenceRemove() throws Exception {
    autoFlushInTheMiddle(true);
  }

  private void autoFlushInTheMiddle(boolean commentToItemReference) {
    // creating an item
    Session session = sessionFactory.openSession();
    Transaction tx = session.beginTransaction();
    
    Item item = new Item();
    session.save(item);
    assertEquals(0, item.comments.size());
    
    tx.commit();
    session.close();
    
    // reading back the item, add two comments, auto-flush, delete one
    session = sessionFactory.openSession();
    tx = session.beginTransaction();
    
    item = (Item) session.get(Item.class, item.id);
    
    Comment comment1 = new Comment(); comment1.item = item;
    item.comments.add(comment1);
    
    Comment comment2 = new Comment(); comment2.item = item;
    item.comments.add(comment2);

    // forcing an auto flush
    session.createCriteria(Item.class).list();
    
    item.comments.remove(comment1);
    if (commentToItemReference) comment1.item = null;
    
    tx.commit();
    session.close();

    // check that we have one comment
    session = sessionFactory.openSession();
    
    item = (Item) session.get(Item.class, item.id);
    assertEquals(1, item.comments.size());
    
    session.close();
  }

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list