Search code examples
javaspringjpaspring-booteclipselink

JPA - does not work cascada type all


I have a problem with saving the list of entities in the database.

I have entity

@Entity
@Table(name = "movies")
@Data
public class MovieEntity {

    @Id
    @Column(unique = true, updatable = false)
    @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "movie", cascade = CascadeType.ALL)
    private Set<MovieDescription> descriptions;
}

with classes

@Entity
@Data
@EqualsAndHashCode(callSuper = true)
@DiscriminatorValue(value = MovieField.Values.DESCRIPTION)
public class MovieDescription extends MovieInfo {

    private String description;
}

which inherits from

@Entity
@Table(name = "movies_info")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")
@Data
public class MovieInfo {

    @Id
    @Column(unique = true, updatable = false)
    @GeneratedValue
    private Long id;

    @ManyToOne
    private MovieEntity movie;
}

Although I am using cascade = CascadeType.ALL when using such a code

final MovieEntity movie = new MovieEntity();
    movie.setStatus(EditStatus.WAITING);
    movie.setTitle(movieDTO.getTitle());
    movie.setType(movieDTO.getType());
    movieDTO.getDescription().ifPresent(description -> {
        MovieDescription movieDescription = new MovieDescription();
        movieDescription.setDescription(description);
        movie.getDescriptions().add(movieDescription);
    });
this.movieRepository.save(movie);

is saved to the database the object itself MovieEntitywithout MovieDescription. The mapped list does not save to the database. Why?


Solution

  • In your case MovieDescription class is the relation owner. This is implied by

    @OneToMany(*mappedBy = "movie"*, cascade = CascadeType.ALL)
    private Set<MovieDescription> descriptions;
    

    JPA persists relations only with owner sides but you are not setting a MovieEntity link in your description

        MovieDescription movieDescription = new MovieDescription();
        movieDescription.setDescription(description);
        movie.getDescriptions().add(movieDescription);
    

    Add the next line for it to work:

        movieDescription.setMovie(movie);