javapostgresqlspring-bootspring-dataspring-data-jdbc

How to save one-to-many entities to PostgreSQL with Spring Data JDBC?


I am trying to save one-to-many entities to PostgreSQL database using Spring Boot and Spring Data JDBC.

Main application code:

@SpringBootApplication
public class TvApplication
{
    @Autowired
    private SeasonRepository seasonRepository;
    @EventListener(ApplicationReadyEvent.class)
    public void saveToDatabase()
    {
        Episode episode1 = new Episode("firstEpisode");
        Episode episode2 = new Episode("secondEpisode");
        Season season = new Season("firstSeason");
        season.addEpisode(episode1);
        season.addEpisode(episode2);
        seasonRepository.save(season);
    }
}

Season class:

@Table("season")
public class Season
{
    @Id
    @Column("id")
    private long id;
    @Column("name")
    private String name;
    @MappedCollection(idColumn = "id", keyColumn = "seasonid")
    private List<Episode> episodes;
    public Season(long id, String name, List<Episode> episodes)
    {
        this.id = id;
        this.name = name;
        this.episodes = episodes;
    }
    public Season(String name)
    {
        this(0, name, new ArrayList<>());
    }
    public void addEpisode(Episode episode)
    {
        episodes.add(episode);
    }

Episode class:

@Table("episode")
public class Episode
{
    @Id()
    @Column("id")
    private long id;
    @Column("name")
    private String name;
    public Episode(long id, String name)
    {
        this.id = id;
        this.name = name;
    }
    public Episode(String name)
    {
        this(0, name);
    }

What I get is this exception:

org.postgresql.util.PSQLException: ERROR: insert or update on table "episode" violates foreign key constraint "episode_seasonid_fkey"
Detail: Key (seasonid)=(0) is not present in table "season"

I think that Spring cannot read auto-generated key from table "season".


Solution

  • Try to change your code like this:

    @MappedCollection(idColumn = "seasonid")
    private Set< Season > season = new HashSet<>();
        
    public void addSeason(Season s) {
        this.season.add(s);
    }
    

    Then change your Episode class as follows:

    Table("episode")
    public class Episode
    {
        @Id
        private long id;
        /// rest of the stuff
    }
    

    Finally, remove this part: this(0, name, new ArrayList<>());