我有一个简单的OneToMany关联2对象Parent&孩子如下图所示。
家长实体
@Entity
public class Parent {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@Version
private Long version;
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
List<Child> children = new ArrayList<Child>();
....
}
子实体
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@Version
private Long version;
...
}
以下是我的测试,它加载一个现有的父项添加一个子项并在父项上调用EntityManager.merge()。
@Test
public void testParent(){
Parent parent = (Parent) dao.loadParent(Parent.class, parentId);
Child c = new Child();
c.setName("c");
parent.getChildren().add(c);
dao.mergeEntity(parent);
Assert.assertNotNull(c.getId());
}
测试id的主键失败的断言。我看到记录正在数据库中正确插入,并且主键已自动分配。
我的所有DAO调用都围绕事务处理,传播为必需。
答案 0 :(得分:13)
EntityManager.merge(..)
获取一个实例并返回一个托管的实例。在瞬态实例的情况下,它返回一个新实例(不修改原始实例)
因此,mergeEntity(..)
方法return em.merge(entity)
答案 1 :(得分:0)
由于您的id由数据库设置,JPA / Hibernate只能在SQL语句发送到数据库后设置它。如果将Hibernate配置为显示sql语句或将日志更改为DEBUG,则可能会在调用mergeEntity
时看到没有发出SQL语句。
使测试工作的一种方法应该是在对子id进行断言之前添加em.flush()。
管理事务的方式可能存在问题,但需要查看DAO的代码以及在单元测试中获取DAO引用的方式。