实体类
// 标签类
@Entity
public class Label {
@Id
@Column(name = "lid",unique = true,nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer lid;
private String tag;
@ManyToMany(fetch = FetchType.EAGER)
@Cascade(value = {CascadeType.ALL}) // 设置级联关系
@JoinTable(name = "song_label",// 指定第三张表
joinColumns = {@JoinColumn(name = "label_id")},//本表与中间表的外键对应
inverseJoinColumns = {@JoinColumn(name = "song_id")}
)
private Set<Song> songs = new HashSet<>();
// setter and getter
}
// 歌曲类
@Entity
public class Song {
@Id
@Column(name = "sid",unique = true,nullable = false)
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer sid;
private String title;
private String special;
@ManyToMany(fetch = FetchType.EAGER)
@Cascade(value = { CascadeType.ALL})
@JoinTable(
name = "song_label",
joinColumns = {@JoinColumn(name = "song_id")},//本表与中间表的外键对应
inverseJoinColumns = {@JoinColumn(name = "label_id")}
)
private Set<Label> labels = new HashSet<>();
// setter and getter
}
关联关系: 一首歌曲可以对应多个标签,一个标签可以对应多首歌曲
遇到的级联保存问题: 在添加已经存在的标签记录时保错org.hibernate.PersistentObjectException: detached entity passed to persist
测试代码
@Test
public void test1() {
Song song = new Song();
song.setSpecial("等你下课");
song.setTitle("等你下课");
Label label1 = new Label();
label1.setTag("华语");
Label label2 = new Label();
label2.setTag("内地");
song.getLabels().add(label1);
song.getLabels().add(label2);
this.songDao.save(song);//因设置级联关系CascadeType.ALL相应会在Label表添加记录
}
@Test
public void test123(){
Song song = new Song();
song.setSpecial("流星花园");
song.setTitle("北极星的眼泪");
Label label1 = this.labelDao.findByTag("爱情");
Label label2 = this.labelDao.findByTag("华语");
if (label2 == null){
label2 = new Label();
label2.setTag("华语");
}
if(label1 == null){
label1 = new Label();
label1.setTag("爱情");
}
song.getLabels().add(label1);
song.getLabels().add(label2);
this.songDao.save(song);// 报错org.hibernate.PersistentObjectException: detached entity passed to persist: com.example.data.bean.Label
}
test1()能够添加成功,到了test2时由于Label表存在"华语"这条记录,保存会出错
疑问:如何在Label表存在记录时执行更新而不是保存?
在此先感谢大神路过指点迷津哈哈
只需要将CascadeType.ALL修改为CascadeType.MERGE
然后在新增数据时自己手动关联表即可