-->
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.  [ 9 posts ] 
Author Message
 Post subject: Delete an item from a List
PostPosted: Thu Dec 13, 2007 8:28 pm 
Newbie

Joined: Thu Dec 13, 2007 8:18 pm
Posts: 7
Need help with Hibernate? Read this first:
http://www.hibernate.org/ForumMailingli ... AskForHelp

Hibernate version: 3.2.5.ga

Name and version of the database you are using:MySQL 5.0.18

Hello All,

I am new to hibernate so please excuse any broach in protocol. I have a uni-directional List of objects that I have mapped as one to many (mapping code to follow)

Code:
  @OneToMany(cascade = CascadeType.ALL)
  @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
  @JoinTable(name = "WIDGET_CONTAINER_WIDGETS", joinColumns = {@JoinColumn(name = "WIDGET_CONTAINER_ID", nullable = false)}, inverseJoinColumns = @JoinColumn(name = "WIDGET_ID", nullable = false))
  @org.hibernate.annotations.IndexColumn(name = "WIDGET_POSITION")


My test executes the following code:
Code:
      final Transaction tx = session.beginTransaction();
      final WidgetContainer theContainer = (WidgetContainer)session.get(WidgetContainer.class, containerId);
      assertNotNull(theContainer);
      final Widget widget2 = theContainer.getWidgets().get(1);
      final List<Widget> widgetList = theContainer.getWidgets();
      // remove the widget from the list
      widgetList.remove(widget2);
      // delete the widget from the persistence model
      session.delete(widget2);
      session.saveOrUpdate(theContainer);
      tx.commit();


I am getting the following exception when I attempt to remove an item from the list:
Code:
java.lang.UnsupportedOperationException
   at java.util.AbstractList.remove(AbstractList.java:172)
   at org.hibernate.collection.PersistentList.remove(PersistentList.java:319)


I am certain that there is user error involved here, but after searching the forums and Google all day I haven't gotten any lead on what I might be doing wrong.

If anyone can offer any advice or insight either into my issue specifically or mapping Lists that I might have missed I would appreciate it.

Thank you for your help,
Dave


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 2:26 am 
Beginner
Beginner

Joined: Fri Jun 25, 2004 11:47 am
Posts: 34
Hi,

I would try 2 things:
1. Remove your final declaration,
2. Remove your session.delete(..)

rgds,


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 11:40 am 
Newbie

Joined: Thu Dec 13, 2007 8:18 pm
Posts: 7
Hello,

I tried removing both the final qualifier and the session.delete() call. Neither had any effect on the behavior I am seeing. Thank you very much for the advice though.

Dave


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 2:07 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
dritter wrote:
Hello,

I tried removing both the final qualifier and the session.delete() call. Neither had any effect on the behavior I am seeing. Thank you very much for the advice though.

Dave

You don't need the delete line neither the saveOrUpdate line. Just remove the entity from list and flush the session, commit the transaction. Hibernate will take care of deleting the child from database since you have specified DELETE_ORPHAN cascade option.


Farzad-


ps. If this still doesn't work give a sample code that doesn't work and I will change it in a way it works.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 2:20 pm 
Newbie

Joined: Thu Dec 13, 2007 8:18 pm
Posts: 7
Thank you for the advice about removing the delete call. I was just reading about transitive persistence and it too mentioned that merely removing the item from the collection should be sufficient to trigger a delete.

I modified my test code to look like this:
Code:
    {
      final Transaction tx = session.beginTransaction();
      final WidgetContainer theContainer = (WidgetContainer)session.get(WidgetContainer.class, containerId);
      assertNotNull(theContainer);
      // Remove Widget 2
      theContainer.getWidgets().remove(1);
      tx.commit();
    }


Unfortunately I am still seeing the same exception at run time that I originally noted:

Code:
java.lang.UnsupportedOperationException
   at java.util.AbstractList.remove(AbstractList.java:172)
   at org.hibernate.collection.PersistentList.remove(PersistentList.java:319)


This is the mapping code I have for the list I am attempting to remove from:
Code:
  @OneToMany(cascade = CascadeType.ALL)
  @JoinTable(name = "WIDGET_CONTAINER_WIDGETS",
                   joinColumns = {@JoinColumn(name = "WIDGET_CONTAINER_ID", updatable = true)},
                   inverseJoinColumns = @JoinColumn(name = "WIDGET_ID", updatable = true))
  @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
  @org.hibernate.annotations.IndexColumn(name = "WIDGET_POSITION")
  private List<Widget> widgets;


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 2:44 pm 
Newbie

Joined: Tue Nov 27, 2007 3:17 am
Posts: 5
If u don't mind may i know the List implementation class u have initialized in ur POJO class. In general collections throw such kind of error(UnsupportedOperationException) when their implementation class does n't support remove() method. So, plz make sure ur collection supports it or not.

Plz reply me.


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 2:55 pm 
Expert
Expert

Joined: Wed Apr 11, 2007 11:39 am
Posts: 735
Location: Montreal, QC
dritter wrote:
Thank you for the advice about removing the delete call. I was just reading about transitive persistence and it too mentioned that merely removing the item from the collection should be sufficient to trigger a delete.


I believe it has something to do with your list instance as the other guy pointed out. I did a little test with your code and it seems to be happily working for me. I did it in JPA but there is hardly a difference here for you:

Code:
package test.model.data.jpa;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

/**
* @author Farzad Kohantorabi
* @created Dec 14, 2007
*/

@Entity
@Table(name = "WidgetContainer")
public class WidgetContainer {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @OneToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "widgetcontainerwidget",
            joinColumns = {@JoinColumn(name = "widgetcontainerid", updatable = true)},
            inverseJoinColumns = @JoinColumn(name = "widgetid", updatable = true))
    @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
    @org.hibernate.annotations.IndexColumn(name = "WIDGET_POSITION")
    private List<Widget> widgets = new ArrayList<Widget>();

    public List<Widget> getWidgets() {
        return widgets;
    }
}


and

Code:
package test.model.data.jpa;

import javax.persistence.*;


@Entity
@Table(name = "widget")
public class Widget {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

}


and the test code is:

Code:
import test.model.data.jpa.Item;
import test.model.data.jpa.WidgetContainer;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import org.hibernate.Transaction;

/**
* @author Farzad Kohantorabi
* @created Dec 10, 2007
*/
public class Driver5 {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1");
        EntityManager em = emf.createEntityManager();

        em.getTransaction().begin();
        final WidgetContainer theContainer = em.find(WidgetContainer.class, (long) 1);
        // Remove Widget 2
        theContainer.getWidgets().remove(1);
        em.getTransaction().commit();

        em.close();
        emf.close();
    }
}


and it runs with no problem.


Farzad-


Top
 Profile  
 
 Post subject:
PostPosted: Fri Dec 14, 2007 4:23 pm 
Newbie

Joined: Thu Dec 13, 2007 8:18 pm
Posts: 7
I re-wrote my test to use the EntityManager like you suggested and it ran correctly for me as well. Does anyone have any idea why the EntityManager can execute this code but the SessionFactory seems to have problems? Can anyone else see if they can reproduce the behavior I am seeing with the SessionFactory?

Thanks,
Dave


Top
 Profile  
 
 Post subject:
PostPosted: Sat Dec 15, 2007 1:40 am 
Newbie

Joined: Thu Dec 13, 2007 8:18 pm
Posts: 7
I think I figured out what is going on and why the EntityManager code appeared to work where the SessionManager did not.

In the setUp() method for my test there is code that adds a new Container and a list of Widgets. This graph is being persisted to the database with a session.save() call and the whole thing was wrapped in a begin/commit transaction block. I assumed that this would be all that was necessary to persist the data to the database and then fetch it back to modify it.

What I found was that Hibernate was not persisting the data when the commit() call was made and when I went later on to access the list I was getting something from the 1st level Session cache (even with this knowledge I'm a little unsure why the list seemed partially populated, but all the dark magic that goes on with hibernate caching is still somewhat unclear to me).

I believe that the test was working with the EntityManager because I was then closing the Session and opening a new EntityManager connection. I think the close() call was causing a flush to occur on the original session and the data to be sent to the DB.

In short what I did was add a session.flush() after the commit() call to my setUp() method and my code executes correctly with the SessionManager now.

I guess I need to do some more reading about transactional control and the flush() method.

Thank you all for your advice on help with my question. I look forward to participating in this forum more (hopefully adding knowledge rather than confusion, eh?) :-)

Thanks,
Dave


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