views:

282

answers:

1

Im trying to remove an entity which has a unique PK like : 80253

I remove this entity by doing the follow lines of code:

myEntityType1 = getEntityManager().find(MyEntityType1.class, 80253);
getEntityManager().remove(myEntityType1);
getEntityManager().flush();

These bits of code actually deletes the rows from my database and all its cascading objects properly, and Im very happy about this. Now the problem occurs when I now need to create a similar entity that uses the same primary key (which should now be gone right?).

MyEntityType2 myEntityType2 = new MyEntityType2 ();
myEntityType2.copyData(myEntityType1); //access the data from the other object
//and retrieves the id 80253. myEntityType2 now has 80253 as ID.
getEntitymanager().persist(myEntityType2);

Now this is where I get a unique constraint SQL error. Im trying to insert a ID which already exists and the changes are automatically rolled back (the old entity is no longer deleted). This happens after I see in my logger that toplink has deleted the records of the old entity.

Does anyone know how this happens, and why its not working? For the record Ive tried merging, closing, clearing of the entityManager, but nothing seems to work.

It seems to me that JPA might do some bad caching or something. I hope someone has a good answer for me! =)

Update: Theres no longer an issue with unique ID constraints, but I create a new subclass with the same primary key which has been deleted I get the following exception:

Exception Description: Trying to invoke [setApprovedWhen] on the object [null].  The 
number of actual and formal parameters differs, or an unwrapping conversion has failed.
Internal Exception: java.lang.IllegalArgumentException: object is not an instance of 
declaring class

It seems to me that it wont let me change the object into a different subclass?

+1  A: 

EDIT: Try with explicitly start and commit transaction.

Deleting an entity is as simple as calling EntityManager method remove(Object entity) as the following example shows. The entity you delete must be managed: that is, it must have been previously read in the current persistence context.

entityManager.getTransaction().begin();
myEntityType1 = getEntityManager().find(MyEntityType1.class, 80253);
getEntityManager().remove(myEntityType1);
entityManager.getTransaction().commit();

When the transaction is completed, or you call EntityManager method flush(), the entity will be deleted. In a container managed persistence context the transaction boundaries will be controlled by the container.

Svetlozar Angelov
In the above code I remove myEntityType1 like this: myEntityType1 = getEntityManager().find(MyEntityType1.class, 80253);getEntityManager().remove(myEntityType1);getEntityManager().flush();
ChrisAD
You copy the object before deleteing reight?
Svetlozar Angelov
The object itself is never deleted, but it should no longer exist in database right? So JPA calls the INSERT INTO query the PK should no longer be in database. I just found out this tho: "Just as with the persist and merge methods, the DELETE(em.remove) statement is not necessarily issued immediately but is guaranteed to be issued at some point." ... This might be where my logic fails. I thought flush would force it to run right away tho?
ChrisAD
So to be clear - find, copy, remove, flush, insert, this is what you do, in this order?
Svetlozar Angelov
Yes this is correct
ChrisAD
I cant explicity start and commit transactions because JTA is handling this. the flush() method should explicit commit all changes for me. if I try to use the transaction I get this exception: Exception Description: Cannot use an EntityTransaction while using JTA.
ChrisAD