Announcement Announcement Module
Collapse
No announcement yet.
Spring Data JPA with @OneToOne relation fails to update already persisted entity Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Data JPA with @OneToOne relation fails to update already persisted entity

    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.

    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
    }

  • #2
    I think I triggered a bug in the EclipseLink implementation. For people who stumble upon the same problems, here a few helpful links:

    http://chandanpandey.com/2012/12/22/...-entity-in-jpa
    https://bugs.eclipse.org/bugs/show_bug.cgi?id=324941

    The workaround was to disallow the @OneToOne(cascade = CascadeType.ALL) (instead use cascade = {CascadeType.MERGE, CascadeType.REFRESH, CascadeType.REMOVE, CascadeType.DETACH}) and set orphanRemove to false.

    Hope this helps anyone.

    Comment

    Working...
    X