Uploaded image for project: 'Hibernate ORM'
  1. HHH-12311

OneToMany orphans are not removed from the DB

    Details

    • Type: Bug
    • Status: Open
    • Priority: Major
    • Resolution: Unresolved
    • Affects Version/s: 5.0.12
    • Fix Version/s: None
    • Component/s: hibernate-core
    • Labels:
    • Environment:
      Darwin Kernel Version 17.4.0 x64
      Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
      H2 1.4.196
    • Bug Testcase Reminder (view):

      Bug reports should generally be accompanied by a test case!

    • Last commented by a user?:
      true
    • Sprint:

      Description

      My log properties are set to:

      logging.level.org.hibernate.SQL: TRACE
      logging.level.org.hibernate.event.internal: TRACE
      logging.level.org.hibernate.engine.spi.CollectionEntry: TRACE
      logging.level.org.hibernate.engine.spi: TRACE
      logging.level.org.hibernate.engine.internal: TRACE
      

      I have two entities: `Job` and `Step`
      Job has a oneToMany relationship with Step which is marked with `orphanRemoval = True`.

          @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
          @JoinTable(name = "JOB_STEP")
          private List<Step> steps;
      

      Expected behavior is when a certain step is removed from `steps` list, DELETE queries should be executed on `STEP` and `JOB_STEP` tables.

      First case, the expected behavior occurs when following code is executed:

      Job job = new Job("Test");
      Step step = new Step("Test");
      job.addStep(step);
      repository.save(job);
      job.removeStep(step);
      repository.save(job);
      

      I see three expected log messages:

      o.h.e.i.AbstractFlushingEventListener: Flushed: 0 insertions, 0 updates, 1 deletions to 2 objects
      org.hibernate.SQL: delete from job_step where job_id=?
      org.hibernate.SQL: delete from step where id=?
      

      ---------------------------------------------------------------------------------

      Second case, when `orphanRemoval = true` doesn't invoke the deletion of orphans from the DB.

      Job job = new Job("Test");
      Step step = new Step("Test");
      repository.save(job); //This causes the bug to happen
      job.addStep(step);
      repository.save(job);
      job.removeStep(step);
      repository.save(job);
      

      After the above code is executed, I can still see entries in STEP and JOB_STEP tables in the DB.

      Following log is printed:

      Flushed: 0 insertions, 0 updates, 0 deletions to 2 objects

      ---------------------------------------------------------------------------------
      ---------------------------------------------------------------------------------

      I've been trying to find the root cause of this problem for few weeks now through debugging the Hibernate's source code. But it didn't really help. However, I noticed few abnormal things that might be helpful for you:

      1) During debugging, I stumbled upon this method `resetStoredSnapshot` from `org.hibernate.engine.spi.CollectionEntry` that essentially just wipes the stored snapshot of Steps that later on causes Hibernate not to find orphans. While in the first case, when Hibernate works as expected, `resetStoredSnapshot` is not executed at all.

      2) I noticed that java.util.List of Steps starts working aberrantly once it gets converted to org.hibernate.collection.PersistentList by Hibernate

      ---------------------------------------------------------------------------------

      The workspace with reproduced bug is here: https://github.com/yeralin/ReproduceBug

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              daniyaryeralin Daniyar Yeralin
              Participants:
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated: