Spring 数据@ManyToMany 更新和创建实体
Spring Data @ManyToMany update and create entity
我认为用现有实体保存新实体是一个很常见的问题(@ManyToMany
关系)
Place
型号
@Entity
@Table(name = "places")
public class Place implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Getter
private Long id;
@Getter
@Setter
@ManyToMany(mappedBy = "places", cascade = {CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH})
private Set<Tag> tags = new HashSet<>();
}
Tag
型号
@Entity
@Table(name = "tags")
public class Tag implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Getter
private Long id;
@Getter
@Setter
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.DETACH})
private Set<Place> places = new HashSet<>();
public void addPlace(Place placeToPersist) {
this.places.add(placeToPersist);
}
}
这就是我如何保存它。关键是我想 link 放置数据库中现有的标签,但如果标签是新的,它应该保存它。
public void processForm(Place placeToPersist, Set<Tag> tagsToCheck) {
Set<Tag> tmpSet = new HashSet<>();
for (Tag t : tagsToCheck) {
Tag tagFromDatabase = tagService.findByName(t.getName());
if (tagFromDatabase == null) {
t.addPlace(placeToPersist);
tagService.save(t); //why I can't save here my tag?
tmpSet.add(t);
} else {
tagFromDatabase.addPlace(placeToPersist);
tmpSet.add(tagFromDatabase);
}
}
placeToPersist.setTags(tmpSet);
placeService.save(placeToPersist);
}
日志
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: pl.project.app.model.Place
尝试将@Transactional 放在method/class 上或自动装配一个TransactionTemplate 以用于执行查询
why I can't save here my tag?
正如错误所说:因为您正在尝试保存引用了地点的标签,尽管地点尚未持久。由于没有为 SAVE(或 PERSIST,取决于 save() 方法的作用)操作设置级联,因此在保存标签时不会保存 Place。
所以,先保存地点,然后将地点添加到标签并保存标签(或者保存标签,然后将地点添加到标签)。
我认为用现有实体保存新实体是一个很常见的问题(@ManyToMany
关系)
Place
型号
@Entity
@Table(name = "places")
public class Place implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Getter
private Long id;
@Getter
@Setter
@ManyToMany(mappedBy = "places", cascade = {CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH})
private Set<Tag> tags = new HashSet<>();
}
Tag
型号
@Entity
@Table(name = "tags")
public class Tag implements Serializable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Getter
private Long id;
@Getter
@Setter
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.REMOVE, CascadeType.REFRESH, CascadeType.DETACH})
private Set<Place> places = new HashSet<>();
public void addPlace(Place placeToPersist) {
this.places.add(placeToPersist);
}
}
这就是我如何保存它。关键是我想 link 放置数据库中现有的标签,但如果标签是新的,它应该保存它。
public void processForm(Place placeToPersist, Set<Tag> tagsToCheck) {
Set<Tag> tmpSet = new HashSet<>();
for (Tag t : tagsToCheck) {
Tag tagFromDatabase = tagService.findByName(t.getName());
if (tagFromDatabase == null) {
t.addPlace(placeToPersist);
tagService.save(t); //why I can't save here my tag?
tmpSet.add(t);
} else {
tagFromDatabase.addPlace(placeToPersist);
tmpSet.add(tagFromDatabase);
}
}
placeToPersist.setTags(tmpSet);
placeService.save(placeToPersist);
}
日志
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: pl.project.app.model.Place
尝试将@Transactional 放在method/class 上或自动装配一个TransactionTemplate 以用于执行查询
why I can't save here my tag?
正如错误所说:因为您正在尝试保存引用了地点的标签,尽管地点尚未持久。由于没有为 SAVE(或 PERSIST,取决于 save() 方法的作用)操作设置级联,因此在保存标签时不会保存 Place。
所以,先保存地点,然后将地点添加到标签并保存标签(或者保存标签,然后将地点添加到标签)。