Spring-JPA:更新父实体无法保留新的子实体,而是将它们解释为Transient

前端之家收集整理的这篇文章主要介绍了Spring-JPA:更新父实体无法保留新的子实体,而是将它们解释为Transient前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我是Spring / JPA / Hibernate的新手,虽然听起来很简单,但事实并非如此.我可以使用一些帮助.

我有一个父实体,其中包含子实体列表.我会用这些来简化讨论:

@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @OneToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL,mappedBy="parent")
    private List

第1轮,我创建一个新的父级和一个新的子级,将子级添加到父级列表并在子级上设置父级.当我保存父母时,孩子也被保存.

@Transactional(propagation=Propagation.REQUIRES_NEW)
void create() {
    Parent parent = new Parent();
    Child  child  = new Child();
    parent.add(child);
    child.setParent(parent);
    parent = repository.save(parent);
}

现在,第2轮,我添加了一个新的孩子:

@Transactional(propagation=Propagation.REQUIRES_NEW)
void update() {
    Parent parent = repository.findOne(parentID);
    Child newChild = new Child();
    newChild.setParent(parent);
    parent.add(newChild);
    parent = repository.save(parent);
}

但是,这次新孩子永远不会坚持下去!

我已尝试过大多数CascadeType,@ GeneratedValue GenerationType,@ Transaction传播类型……

通过休眠来追踪这个(痛苦!),这是我发现的:

>第二次保存时,问题出在第二个(新)孩子身上.
>问题似乎是,当需要坚持父母的子列表时
新子项不在EntityManager中(尚未),因此被认为是瞬态的.
>因此,它实际上是作为null传递给链,导致以下结果:

06003

>可能有用的是,在我的实际代码中,“Child”也有一个子实体的地图.由于“瞬态”盗用,这个“价值”被传递为零.
>我一直在使用repository.saveAndFlush()来保持调试的同步.当我只使用.save()时,我会调用@PreUpdate EntityListener,但@PostUpdate监听器永远不会被调用.
>如果孩子刚刚坚持或至少在坚持父母之前获得了Id,似乎不会有问题.但手动执行此操作似乎也适得其反.不过,这是我能想到的唯一选择.

谢谢阅读.任何帮助将非常感激!

最佳答案
你所展示的所有东西看起来都很正常,所以问题可能在于你提到的地图.我在Github上有一个working example of a bidirectional one-to-many using Spring Data JPA.您可以查看代码或克隆并运行它:

git clone git://github.com/zzantozz/testbed tmp
cd tmp/spring-data
mvn -q compile exec:java -D exec.mainClass=rds.springdata.JpaBidioneToManyExample

猜你在找的Spring相关文章