我有一个具有多对多关系的基本项目。有2个类Parent
和Child
,关系的所有者是类Parent
。当父实体被持久化时,子实体也会被持久化(这是期望的行为)。但相反,当子实体被持久化时,父实体不会被持久化。
如何让父实体与子实体同时保留?下面的代码给出了允许重现问题的 spring-boot 类,在 logger.info("---> 2nd fetch allparents");
之后,我期望有 5 个 parent ,但我有只有两个。
这是我的实体类:
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
// @JoinTable => owner of the relationship
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "parent_child",
joinColumns = @JoinColumn(name = "parent_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "child_id", referencedColumnName = "id"))
private Set<Child> children;
}
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String name;
@ManyToMany(mappedBy = "children")
private Set<Parent> parents;
// getters and setters
}
存储库
public interface ChildRepository extends JpaRepository<Child, Long> {}
public interface ParentRepository extends JpaRepository<Parent, Integer> {}
springboot应用
@SpringBootApplication
public class Application implements CommandLineRunner {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
@Autowired
private ParentRepository parentRepository;
@Autowired
private ChildRepository childRepository;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
@Transactional
public void run(String... strings) throws Exception {
// save a couple of parents
Child childA = new Child("Child A"); Child childB = new Child("Child B"); Child childC = new Child("Child C");
Parent parentA = new Parent("Parent A", new HashSet<>(Arrays.asList(childA, childB))); Parent parentB = new Parent("Parent B", new HashSet<>(Arrays.asList(childA, childC)));
parentRepository.saveAll(Arrays.asList(parentA, parentB));
// fetch all parents
logger.info("---> 1st fetch all parents");
for (Parent parent : parentRepository.findAll()) {
logger.info(parent.toString());
}
// save a couple of children
Parent parentD = new Parent("Parent D"); Parent parentE = new Parent("Parent E"); Parent parentF = new Parent("Parent F");
Child childD = new Child("Child D", new HashSet<Parent>(Arrays.asList(parentD, parentE))); Child childE = new Child("Child E", new HashSet<Parent>(Arrays.asList(parentE, parentF)));
childRepository.saveAll(Arrays.asList(childD, childE));
// fetch all children
logger.info("---> 1st fetch all children");
for (Child child : childRepository.findAll()) {
logger.info(child.toString());
}
// fetch all parents
logger.info("---> 2nd fetch all parents");
for (Parent parent : parentRepository.findAll()) {
logger.info(parent.toString());
}
// fetch all children
logger.info("---> 2nd fetch all children");
for (Child child : childRepository.findAll()) {
logger.info(child.toString());
}
}
}
最佳答案
使用 JPA,当您想要将更新传播到关系项时,您必须指定要应用的传播类型。
因此,当您定义关系ManyToMany时,您可以添加级联类型“PERSIST”来传播实体Parent的指令INSERT
@ManyToMany(mappedBy = "children", cascade = CascadeType.PERSIST)
private Set<Parent> parents;
这里是 Hibernate 的完整规范Springboot使用
如果您使用注释,您可能已经注意到级联属性将 CascadeType 数组作为值。 JPA 中的级联概念与上面描述的操作的传递持久性和级联非常相似,但语义和级联类型略有不同:
CascadeType.PERSIST
:将持久(创建)操作级联到 关联实体 persist() 被调用或者实体被管理CascadeType.MERGE
:将合并操作级联到关联的 实体(如果调用 merge() 或实体受管理)CascadeType.REMOVE
:将删除操作级联到关联的 实体(如果调用了delete())CascadeType.REFRESH
:级联 如果调用了refresh(),则对关联实体进行刷新操作CascadeType.DETACH
:将分离操作级联到关联的 实体,如果 detach() 被调用 CascadeType.ALL:以上所有
关于java - Spring JPA在多对多关系中持久化子级时如何持久化父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57524653/