Search code examples
javadatabasespring-bootjpacascade

CascadeType.ALL doesn't save the children. the child doesn't get presist and saved


I have three Entity such as following:

@Table(name = "input")
@Entity
@Data
public class CreationInputEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "ID", unique = true, nullable = false, updatable = false)
    Long id;

    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name = "index_id", referencedColumnName = "id")
    IndexEntity index;
}

@Table(name = "index")
@Entity
@Data
public class IndexEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "id", unique = true, nullable = false, updatable = false)
    Long id;

    @OneToOne(mappedBy = "index")
    CreationInputEntity creationInputEntity;

    @NotBlank
    @Column(name = "indexName")
    String indexName;

    @OneToMany(mappedBy = "index", cascade=CascadeType.ALL)
    List<IndexshareEntity> indexshares;
}

@Entity
@Data
public class IndexshareEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    @Column(name = "ID", unique = true, nullable = false, updatable = false)
    public Long id;

....

    @ManyToOne
    @JoinColumn(name="index_id")
    public IndexEntity index;
}

and I have several endpoints. When in first create endpoint, I create the CreationInputEntity endpoint, and saveAndFlush, it shows in database and with debugging that all part of it such as IndexEntity and IndexshareEntity got saved. but after saving and trying to fetch the data with the getRequest, there is a IndexEntity, but it's IndexshareEntity is empty and the IndexshareEntities didn't remained saved in the database.

CreationInputEntity createdCreationInputEntity = inputRepository.saveAndFlush(creationInputEntity);

Where am I doing wrong? why the children does't stay in the database? I thought saveAndFlush with CascadeType.ALL would be enough for saving all parts of the entity?

Thank you in advanced for your helps.


Solution

  • Your case is explained by the fact that at the time of saving, the child IndexshareEntity objects do not contain a reference to the parent IndexEntity object. The relationship between IndexEntity and IndexshareEntity is managed by the IndexshareEntity object, since that is where you joined the @JoinColumn(name="index_id") column. However, at the time of saving, IndexshareEntity objects do not contain a reference to the IndexEntity object, so the IndexEntity object id is not stored in the index_id column. Therefore, when you load the IndexEntity, Hibernate cannot determine the IndexshareEntity objects that are related to it.

    To solve the problem, you must set a reference to the parent object for each child object. This can be done either manually using the IndexshareEntity.setIndex() method, or automatically using the @JsonManagedReference and @JsonBackReference annotations.

    class IndexEntity {
    
      @JsonManagedReference
      @OneToMany(mappedBy = "index", cascade=CascadeType.ALL)
      List<IndexshareEntity> indexshares;
    }
    
    class IndexshareEntity {
    
      @ManyToOne
      @JsonBackReference
      @JoinColumn(name="index_id")
      public IndexEntity index;
    }
    

    Unfortunately, judging by your code, the @JsonManagedReference and @JsonBackReference annotations won't help you.