Hey folks,
so we got this setup: A document has a list of elements and these elements are subclasses of Element, in this example Link. A Link has a @OneToOne relation to Resource. Everything worked as long as we create the whole object graph in one step.
We now changed our code to create an instance of Resource, persist it and pass it to our client (web, objects serialized to JSON). The client creates an instance of the Document and adds a Link with the existing Resource. After that we try to persist the new Document.
At this point the operation fails, because JPA tries to persist the already existing Resource with the same id. I think this happens because the Resource is detached and JPA has no way to determine whether this entity has to be merged or persisted. When I remove the CascadeType.ALL and replace it by CascadeType.MERGE, everything is fine except the Resource is not updated at all.
Basically the workflow is as follows:
- create and persist Resource
- leave transaction
- start transaction
- create Document with Link and (detached) Resource
- error
Is there a problem with our JPA configuration (have a look at our entities)? I'd love to give you a beer sometime if you can give me a hint... :-) TYIA.
Our setup is: EclipseLink 2.4.1, Spring Data JPA 1.3.0 with PostgreSQL 9.2.
so we got this setup: A document has a list of elements and these elements are subclasses of Element, in this example Link. A Link has a @OneToOne relation to Resource. Everything worked as long as we create the whole object graph in one step.
We now changed our code to create an instance of Resource, persist it and pass it to our client (web, objects serialized to JSON). The client creates an instance of the Document and adds a Link with the existing Resource. After that we try to persist the new Document.
At this point the operation fails, because JPA tries to persist the already existing Resource with the same id. I think this happens because the Resource is detached and JPA has no way to determine whether this entity has to be merged or persisted. When I remove the CascadeType.ALL and replace it by CascadeType.MERGE, everything is fine except the Resource is not updated at all.
Basically the workflow is as follows:
- create and persist Resource
- leave transaction
- start transaction
- create Document with Link and (detached) Resource
- error
Is there a problem with our JPA configuration (have a look at our entities)? I'd love to give you a beer sometime if you can give me a hint... :-) TYIA.
Our setup is: EclipseLink 2.4.1, Spring Data JPA 1.3.0 with PostgreSQL 9.2.
Code:
@Entity
public class Document implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@OrderColumn
@JoinColumn(name = "document_id")
private List<Element> elements = new ArrayList<Element>();
// getters and setters
Code:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Element implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "document_id", insertable = false, updatable = false)
private Document document;
// getters and setters
Code:
@Entity
public class Link extends Element {
@Column
private String appearance;
@Column
private String referenceType;
@OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
private Resource resource;
// getters and setters
}
Code:
@Entity
public class Resource {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column
private String uri;
// getters and setters
}