remove in a loop

View: New views
4 Messages — Rating Filter:   Alert me  

remove in a loop

by Nocia :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

I'm using JEE5 with TopLink.

In one of my session bean, I have a method to delete a list of entity which does :

  Query q = em.createQuery(query);
  List<ICRUDEntity> entities = q.getResultList();
  for(ICRUDEntity entity : entities)
    em.remove(entity);
  //em.flush();

But in this case only the first entity of the list is deleted. Add em.flush() at the end doesn't change this behaviour.

The only way to make it work is to add a flush after next remove call:

  Query q = em.createQuery(query);
  List<ICRUDEntity> entities = q.getResultList();
  for(ICRUDEntity entity : entities) {
    em.remove(entity);
    em.flush();
  }

But I don't understand why I'm obligated to use such a workaround.

Have I anything wrong? Is this a bug of toplink?

Thanks for your /*comments*/


 

Re: remove in a loop

by James Sutherland :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

That does not seem possible.  Is an error occurring?  Perhaps turn on logging to finest.

The only thing that I can think of, is all of your object's have the same Id, or perhaps a null Id.

What version of TopLink are you using?  Perhaps try the latest EclipseLink release.

Re: remove in a loop

by Nocia :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Fore sure I find that strange too...

No, I checked the values returned and I did the test both case with exactly the same data.
Here are the results of log :

for the first case with no flush or flush at the end (where I printed the id in the loop):

Printed id : 113
The remove operation has been performed on: AbstractFlow[id=113]
Printed id : 72
The remove operation has been performed on: AbstractFlow[id=72]
Printed id : 119
The remove operation has been performed on: AbstractFlow[id=119]
TX beginTransaction, status=STATUS_ACTIVE
Execute query DeleteObjectQuery(AbstractFlow[id=113])
reconnecting to external connection pool
DELETE FROM flow WHERE (ID = ?)
        bind => [113]
DELETE FROM abstract_flow WHERE (ID = ?)
        bind => [113]
Unregister the object AbstractFlow[id=113]



In the second case:

Printed id : 113

Execute query DeleteObjectQuery(AbstractFlow[id=113])
reconnecting to external connection pool
DELETE FROM flow WHERE (ID = ?)
        bind => [113]
DELETE FROM abstract_flow WHERE (ID = ?)
        bind => [113]
Unregister the object AbstractFlow[id=113]

Printed id : 72

The remove operation has been performed on: AbstractFlow[id=72]
Execute query DeleteObjectQuery(AbstractFlow[id=72])
DELETE FROM flow WHERE (ID = ?)
        bind => [72]
DELETE FROM abstract_flow WHERE (ID = ?)
        bind => [72]
Unregister the object AbstractFlow[id=72]

Printed id : 119

The remove operation has been performed on: AbstractFlow[id=119]
Execute query DeleteObjectQuery(AbstractFlow[id=119])
DELETE FROM flow WHERE (ID = ?)
        bind => [119]
DELETE FROM abstract_flow WHERE (ID = ?)
        bind => [119]


We can see that in both case the delete request are done but only in the second case they are all performed...

I use TopLink version 2.1-b60e-fcs (12/23/2008)

Re: remove in a loop

by James Sutherland :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

The only thing I can think of, is you have another object that still has a reference to the deleted object, that is causing it to be re-persisted.  Otherwise you might need to try to debug it by added a breakpoint into the EclipseLink UnitOfWorkImpl code and inspecting its state.

It could be a bug in TopLink Essentials, try upgrading to the latest EclipseLink release and see if the issue still occurs.