我是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