openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Henno Vermeulen <he...@huizemolenaar.nl>
Subject RE: persisting a new structure with two references to a new object
Date Tue, 16 Jul 2013 12:12:33 GMT
I guess I can answer my own question: just use CascadeType.MERGE anyway.

The workaround I suggested can get very complex for a bit more complex entity graphs because
you may then need to keep track of multiple properties of multiple entities before and after
saving and write their new value and you have to know which entity before merge corresponds
to which after which isn't trivial because new objects don't have (auto generated) id's yet.


JPA cascade already has the ability to correctly do what I want, so simply marking the relation
Contact.department as CascadeType.MERGE (/PERSIST depending on how you persist) solves the
problem. JPA will not insert multiple Departments but correctly make the references to the
same saved Department.

The only possible problem I get is that I may accidentally set a reference to a new Department
outside of the Customer entity graph. If this is a real problem it is possible to add custom
code to guard against this.

Henno


-----Oorspronkelijk bericht-----
Van: Henno Vermeulen [mailto:henno@huizemolenaar.nl] 
Verzonden: dinsdag 16 juli 2013 11:56
Aan: 'users@openjpa.apache.org'
Onderwerp: persisting a new structure with two references to a new object

I have three unpersisted entities, let's call them Customer, Department and Contact.

-          Customer refers to Department using CascadeType.ALL

-          Customer refers to Contact using CascadeType.ALL

-          Contact refers to (the same) Department using no cascade

I wish to save all three new objects by persisting the new Customer; this situation must also
be supported in my UI.
When I do this (through entityManager.merge) I get this error:

new object in persistent field "Contact.department" during attach.  However, this field does
not allow cascade attach. Set the cascade attribute for this field to CascadeType.MERGE or
CascadeType.ALL (JPA annotations) or "merge" or "all" (JPA orm.xml). You cannot attach a reference
to a new object without cascading.

I explicitly do NOT want to cascade persist/merge the Contact.department relation because
Department must always be persisted through Customer.  Contact.department is a simple (nullable)
reference that may later be changed to refer to another Department.

Of course it is logical that I get this error when Contact.department refers to a new Department
when it is not in the object graph that I am persisting. But in this case the new Department
will be cascade persisted through Customer so it's new primary key could in principle be used
for the foreign key Contact.department. So I was hoping that somehow OpenJPA was smart enough
to do this.

One possible way I can think of to implement this logical "save" operation is by explicitly
checking if the Department is new and if so merging it in two steps: first merge the Customer
graph by setting Contact.department = null, then "manually" setting it to the newly saved
Customer.department and merge again.
Unfortunately this is extra code for the same logical "save" operation. Is there some way
to tell OpenJPA to merge without throwing this exception or should I simply use such a workaround?

Henno

Mime
View raw message