当父/子对象同时持久化时,如何在Hibernate + Spring JPA配置中填充外键值?

ske*_*625 4 mysql spring hibernate jpa spring-data-jpa

我有两个对象,父母和孩子.Child有一个外键返回PARENT表(MySQL数据库)中的PARENT_ID字段.

当同时创建/组装父和子对象,并且调用persist时,不会自动填充Child PARENT_ID外键.

示例代码:

@Entity
@Table(name = "PARENT")
public class Parent {
    @Column(name = "PARENT_ID")
    private Long parentId;

    @OneToMany(mappedBy = "parent")
    private List<Child> children;
}

@Entity
@Table(name = "CHILD")
public class Child {
    @Column(name = "CHILD_ID")
    private Long childId;

    @Column(name = "PARENT_ID")
    private Long parentId;

    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;
}
Run Code Online (Sandbox Code Playgroud)

我有两个持久性样本:

1)使用Hibernate EntityManager:

@PersistenceContext
EntityManager em;

...

em.persist(parent);
Run Code Online (Sandbox Code Playgroud)

2)使用Spring Data JPA JpaRepository实例:

public interface ParentRepository extends JpaRepository<Parent, Long> {

}
Run Code Online (Sandbox Code Playgroud)

在我的ParentServiceImpl中:

@Autowired
private ParentRepository parentRepository;

...

public Parent save(Parent parent) {
    return parentRepository.save(parent);
}
Run Code Online (Sandbox Code Playgroud)

填充外键的推荐策略是什么?是否应首先保留Parent对象,然后在该点设置Child对象外键?或者是否可以通过自动或通过引用设置外键来一次性保留所有内容?

编辑:添加了持久性样本.

编辑2(修复!):根据瑞安斯图尔特的第二点解决问题.我从Child对象中删除了Long parentId字段,并在getter上放置了parentId的@Column引用.还要确保正确设置引用(重要的是Child引用回Parent).

Rya*_*art 5

该代码有两个阻止它工作的东西:

  1. 你的实体没有@Id.你可能只是把它关了,因为这是一个例子,但值得指出.
  2. 您已经对列进行了双重映射parent_id.Child具有映射到同一列的Long字段和Parent字段.摆脱龙.这是你追求的父母关系.

在那之后,你有一个完全传统的双向一对多与连接列.如果它不适合您,那么您在创建和保存它们的代码中做错了.很可能,你没有正确地创建对象.使用这些实体的正确代码看起来像这样:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Parent p = new Parent();
Child child = new Child();
child.parent = p;
Child child1 = new Child();
child1.parent = p;
p.children = Arrays.asList(child, child1);
session.save(p);
session.save(p.children.get(0));
session.save(p.children.get(1));
tx.commit();
Run Code Online (Sandbox Code Playgroud)

请特别注意,子项应设置在父项中以及子项中的父项中.不要构建一个半破坏的对象模型,并期望Hibernate清理你的混乱.许多人忽略了这个看似明显的要求,并想知道为什么Hibernate看起来不稳定和/或不可靠.