Georgi created OLINGO-49:
----------------------------
Summary: Create of an owning Entity creates also the inverse
Entity even if it exists
Key: OLINGO-49
URL: https://issues.apache.org/jira/browse/OLINGO-49
Project: Olingo
Issue Type: Bug
Components: odata2-jpa
Affects Versions: 1.0.0, 1.1.0
Reporter: Georgi
Priority: Blocker
Consider the case when you want to add a new Entity (A) to a collection of that
type of entities (List<A>) that belongs to another Entity(B).
A bi-directional JPA relationships, to model the case would be:
A: @ManyToOne
@JoinColumn(name = "B_ID", referencedColumnName="B_ID")
private B b;
B: @OneToMany(mappedBy = "b", cascade = CascadeType.ALL,
fetch=FetchType.EAGER)
private List<A> as;
Notice that the underlying relational model would be constrained so that B_ID
in A's corresponding table is a foreign key and not null. Therefore, when
inserting A rows/entities we need to make sure that B exists and provides us
with a valid id.
With that setup and constraints a create request for a new A that references an
existing B entity with id 3 will send something like this:
HTTP POST <path>/As
"{\"aId\":0\"b\":{\"__metadata\":{\"uri\":\"Bs(3)\"}}}"
The problem is that the inline B entry here is interpreted as new one and
olingo tries to create a new B instance out of it and persist it, instead of
finding the B entity and setting as value to A's property b.
That is, after normalization with normalizeInlineEntries it becomes part of the
oDataEntryProperties map that is passed to the write method with flag
isCreate=true, i.e. all inside is created.
Ultimately, during em.commit this fails with :
javax.persistence.RollbackException: java.lang.IllegalStateException: During
synchronization a new object was found through a relationship that was not
marked cascade PERSIST: B@xxxx
(The object is new because it has been created out of the existing B because
nobody bothered to call persist on it we get this exception. It's kind of
misleading to the real problem here)
The client is obliged to set the referenced property 'b' or otherwise it would
a) violate the underlying relational model constraints 2) there's no other way
to claim to which B entity's aggregation A belongs.
So it's up to the JpaEntity implementation to consider also this case and
distinguish inline requests for new entities from references to existing ones
that need not be created.
--
This message was sent by Atlassian JIRA
(v6.1#6144)