hibernatespring-data-jpaspring-data

Hibernate Found shared references to a collection Exception


I faced an exception related "Found shared references to a collection" and i could not find out any solution to overcome. The Problem Occurs under below conditions.

Let's assume Table-1 and Table-2 like

Table-1
ID   Code Other Columns
1    A    . . . . . 
2    A    . . . . .
3    B    . . . . .


Table-2
ID   Source Other Columns
1    A    . . . . . 
2    A    . . . . .
3    B    . . . . .

class Table1 {
   @Id
   private Long id;
   @Column(name = "CODE")
   private String code;
   @OneToMany
   @JoinColumn(name = "SOURCE", referencedColumnName = "CODE")
   private List<Table2> table2List = new ArrayList<>();
}

class Table2 {
   @Id
   private Long id;
   @Column(name = "SOURCE")
   private String source;
 }

when I load all data of Table-1, there will be 3 elements as usual. The problem starts here. table2List variable of first and second elements (code is A) are the same PersistentBag, the same instance of collection(it has 2 elements) and Hibernate throws Found shared references to a collection Exception when transaction is committed. The Collections are already created by Hibernate not me. it seems hibernate bug according to me. I do not know why hibernate does not create different collections for different elements instead of setting the same collection into different elements. How can i solve this problem?


Solution

  • I found a workaround. just added @Access(AccessType.PROPERTY) over to table2List and updated the setter method to create a new Arraylist instead. it worked properly.

    import javax.persistence.Access;
    import javax.persistence.AccessType;
    
    class Table1 {
      @Id
      private Long id;
      @Column(name = "CODE")
      private String code;
    
      @OneToMany
      @JoinColumn(name = "SOURCE", referencedColumnName = "CODE")
      @Access(AccessType.PROPERTY) // update-1
      private List<Table2> table2List = new ArrayList<>();
    
      // update-2
      public void setTable2List(List<Table2> table2List) {
         this.table2List = new ArrayList<>(table2List);
      }  
      
    }