【问题标题】:Spring data with hibernate: multiple row insert in one-to-many entity without cascade带有休眠的Spring数据:在没有级联的一对多实体中插入多行
【发布时间】:2017-04-15 17:07:22
【问题描述】:

我正在使用 Spring Data 和 Hibernate 作为 Spring Boot 的 JPA 实现。我是新手。 我有一个实体,我在其中维护两个已经存在的实体之间的映射,并且该映射中的条目仅在特定更新时出现。

@Entity
@Table(name = "song_genres")
public class SongGenres {

    public SongGenres(Song song, List<Genre> genres) {
        this.genres = genres;
        this.song = song;
    }

    public SongGenres() {
//        Empty constructor as required by hibernate
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "song_id")
    private Song song;

    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "genre_id")
    private List<Genre> genres;

    public List<Genre> getGenres() {
        return genres;
    }
}

我正在尝试一次插入与一首歌曲相关的所有流派值,使用

SongGenres songGenres = new SongGenres(song, genres);
songGenresRepository.save(songGenres);

但这给出了一个错误

java.sql.SQLException: 字段 'genre_id' 没有默认值

并且 sql 日志显示单行插入

休眠:插入 song_genres (song_id) 值 (?)

如何在没有级联的情况下实现一对多的多行插入?

【问题讨论】:

    标签: mysql hibernate jpa spring-data spring-data-jpa


    【解决方案1】:

    现在,我更改了实体定义,因为两者之间没有太大区别

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "chapter_id")
    private Chapter chapter;
    
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "genre_id", nullable = false)
    private Genre genre;
    

    保存操作就变成了

        List<ChapterGenre> chapterGenres = new ArrayList<>();
        for (Genre genre : genres) {
            chapterGenres.add(new ChapterGenre(chapter, genre));
        }
        chapterGenreRepository.save(chapterGenres);
    

    来自 this one 的结论是,从 Spring 的实现角度来看没有太大区别。

    虽然this ain't best performance mysql-wise。如果 spring data 提供一个简单的单插入 API 会很有趣。

    【讨论】:

    • 章节 - 歌曲...以更容易理解但在这个答案和问题之间可以互换
    【解决方案2】:

    只需在此处“列表类型”为您的列表定义 CASCADE 类型 在列表中添加项目编号并保留主要实体。 你可以阅读更多关于它here

    例如:

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "visitId")
    private Collection<SampleData> lstSampleData;
    

    【讨论】:

    • 嘿,感谢您的回答,就像我在问题中提到的那样,这两个实体都已经存在,并且它是一个特定的更新,它创建了两者之间的映射。否则,我会按照您的建议保持这种关系并级联。
    猜你喜欢
    • 1970-01-01
    • 2015-07-04
    • 2021-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多