jpa-spec
  1. jpa-spec
  2. JPA_SPEC-33

More detailed specification for bidirectional relationships with orphan removal

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Minor Minor
    • Resolution: Invalid
    • Labels:
      None

      Description

      The specification of the orphan removal feature (chapter 2.9) should explicitly specify if the parent reference can be set to null while the foreign key column is defined as NOT NULL.

      Example:
      Given two classes Parent and Child, each persisted in its own database table (PARENT and CHILD). The CHILD table contains a foreign key column PARENT_ID. This column should be NOT NULL, we don't allow orphans in the database . The Java classes implement a bidirectional relationship. The Parent class holds a collection of children and the Child class holds a reference to its parent. See the following two code snippets.

      "Parent.java"
      @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
      private List<Child> children = new ArrayList<Child>();
      
      public Child getChild(int index) {
      	return children.get(index);
      }
      
      public void addChild(Child child) {
      	children.add(child);
      }
      
      public void removeChild(Child child) {
      	children.remove(child);
      }
      
      "Child.java"
      @ManyToOne
      @JoinColumn(name = "PARENT_ID")
      private Parent parent;
      
      public Parent getParent() {
      	return parent;
      }
      
      public void setParent(Parent parent) {
      	this.parent = parent;
      }
      

      The specification should specify the above mentioned NULL-Handling.
      What happens if I load a parent object with a child object from the database, remove the child from the parent and set the reference from the child to the parent to null (as it does not belong to the parent anymore).

      Example code:

      Parent p = entityManager.find(Parent.class, 1);
      Child c = p.getChild(0);
      p.removeChild(c);
      c.setParent(null);
      

      In my opinion this should be allowed even if the foreign key column is NOT NULL, as the child does not belong to the parent anymore. The child object gets removed from the database through the orphan removal feature, the NOT NULL constraint is not violated. Keeping the child-to-parent reference in the object model would leave it in a corrupt state.
      In Hibernate the above code snippet works. Eclipselink however first issues an update statement setting the PARENT_ID to null, violating the NOT NULL constraint. So the above code triggers an exception during flush(). The specification should specify the expected behavior.

        Activity

        janf10 created issue -
        Hide
        mkeith added a comment -

        The default for orphanRemoval in the @OneToMany annotation is false, so automatically removing the child without specifying orphanRemoval = true would be incorrect. Did you just forget to specify the orphanRemoval element in your example?

        Show
        mkeith added a comment - The default for orphanRemoval in the @OneToMany annotation is false, so automatically removing the child without specifying orphanRemoval = true would be incorrect. Did you just forget to specify the orphanRemoval element in your example?
        Hide
        janf10 added a comment -

        Sorry, forgot to add orphanRemoval=true in the example.

        Show
        janf10 added a comment - Sorry, forgot to add orphanRemoval=true in the example.
        Hide
        ldemichiel added a comment -

        Whether this FK column is NOT NULL or not shouldn't affect the removal of both parent and child. This is an implementation issue, not a spec issue, so closing out.

        Show
        ldemichiel added a comment - Whether this FK column is NOT NULL or not shouldn't affect the removal of both parent and child. This is an implementation issue, not a spec issue, so closing out.
        Hide
        ldemichiel added a comment -

        This is an implementation issue, not a spec issue. Orphan removal is neutral as to whether FKs are defined as NOT NULL or not.

        Show
        ldemichiel added a comment - This is an implementation issue, not a spec issue. Orphan removal is neutral as to whether FKs are defined as NOT NULL or not.
        ldemichiel made changes -
        Field Original Value New Value
        Status Open [ 1 ] Closed [ 6 ]
        Resolution Invalid [ 6 ]
        Hide
        janf10 added a comment -

        Regarding orphan removals the specification (2.1 early draft, page 42) specifies that

        Portable applications ... must not reassign an entity that has been orphaned to another
        relationship or otherwise attempt to persist it.

        It is not defined if, given an orphaned entity, portable applications are allowed to set the reference to the parent to null or not. This leads to portability issues between EclipseLink and Hibernate.

        Show
        janf10 added a comment - Regarding orphan removals the specification (2.1 early draft, page 42) specifies that Portable applications ... must not reassign an entity that has been orphaned to another relationship or otherwise attempt to persist it. It is not defined if, given an orphaned entity, portable applications are allowed to set the reference to the parent to null or not. This leads to portability issues between EclipseLink and Hibernate.

          People

          • Assignee:
            Unassigned
            Reporter:
            janf10
          • Votes:
            1 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: