Id not being set when calling EntityManager.merge()
I have a simple OneToMany association between 2 object Parent & Child as shown below.
Parent Entity
@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>();
....
}
Child entity
@Entity
public class Child {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@Version
private Long version;
...
}
Following is my test which loads an existing parent adds a child and calls EntityManager.merge() on the parent.
@Test
public void testParent(){
Parent parent = (Parent) dao.loadParent(Parent.class, parentId);
Child c = new Child();
c.setName("c");
parent.getChildre开发者_开发知识库n().add(c);
dao.mergeEntity(parent);
Assert.assertNotNull(c.getId());
}
The assertion where primary key of the id is tested fails. I see the record being inserted correctly in the database along with the primary key auto assigned.
All my DAO calls are wrapped around transaction with propagation as Required.
EntityManager.merge(..)
gets an instance and returns an instance that is managed. And in case of transient instances it returns a new instance (does not modify the original)
So your mergeEntity(..)
method should return em.merge(entity)
As your id is set by the database, JPA/Hibernate can only set it after the SQL statement had been sent to the database. If you configure Hibernate to display the sql statement or change the log to DEBUG you probably see that no SQL statement is issued when you call mergeEntity
.
One way to make your test work should be to add em.flush() before making the assertion on the child id.
There might may an issue the way you manage the transaction but will require to see the code of the DAO and the way you obtain a reference to the DAO in your unit test.
精彩评论