有人可以解释一下,为什么即使我正在刷新实体,我的父母也没有填充这个孩子?
我在这里包含了parentDao2Test类以及ParentService,ChildService,DBChild和DBParent。 parentDAO和childDao基本简单。 parentDao2Test通过SpringJUnit4ClassRunner junit runner运行。
public class ParentDao2Test {
@Autowired private ParentService parentService;
@Test
public void testCRUD() {
DBParent parent = parentService.createParent();
assertTrue(parent.getId() > 0);
parent = parentService.createChildForParent(parent.getId());
assertTrue(parent.getChilds().size() > 0);
}
}
public class ParentService{
@Autowired ParentDao parentDao;
@Autowired ChildService childService;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public DBParent createParent() {
DBParent parent = new DBParent();
parentDao.persist(parent);
return parent;
}
@Transactional(propagation=Propagation.REQUIRES_NEW)
public DBParent createChildForParent(long parentId) {
DBParent parent = parentDao.findById(parentId);
childService.createChildForParent(parentId);
HashMap<String, Object> props = new HashMap<String, Object>();
props.put("org.hibernate.cacheMode", CacheMode.IGNORE);
parentDao.refresh(parent);
return parent;
}
}
public class ChildService {
@Autowired ChildDao childDao;
@Autowired ParentDao parentDao;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public DBChild createChildForParent(long parentId) {
DBParent parent = parentDao.findById(parentId);
DBChild child = new DBChild();
child.setName("Name");
childDao.persist(child);
parent.addChild(child);
parentDao.persist(parent);
parentDao.flush();
return child;
}
}
@Entity
@Table(name = "Parent")
public class DBParent {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}, orphanRemoval=true)
@JoinColumn(name = "childs", nullable=true)
private Set<DBChild> childs = new HashSet<DBChild>();
public DBParent() {
super();
}
}
@Entity
@Table(name = "child")
public class DBChild {
@Id
@Column(name="id")
@GeneratedValue(strategy=GenerationType.AUTO)
private long id;
@Column(name="name", nullable = false, length=1024)
private String name;
public DBChild() {
super();
}
}
答案 0 :(得分:0)
经过一整天的深度调试,我终于找到了问题的问题。
我看到了这种行为,因为我的事务是在REPEATABLE_READ中配置的(这是默认值)。这意味着Spring保证在同一事务中对相同数据的两次读取将始终返回相同的结果。由于隔离级别优先于我的缓存逐出或实体刷新,即使我刷新或逐出父实体,这也没有效果。
有一种方法可以解决此问题: 将事务隔离级别声明为READ_UNCOMMITTED或READ_COMMITTED。如果您使用的是标准方言,则可能会遇到着名的“标准JPA不支持自定义隔离级别”异常。在这种情况下,您可以应用以下解决方法: 春天3.3:http://amitstechblog.wordpress.com/2011/05/31/supporting-custom-isolation-levels-with-jpa/ 春天3.2:http://shahzad-mughal.blogspot.com/2012/04/spring-jpa-hibernate-support-for-custom.html
为了使我的代码能够工作,我不得不改变以下方法:
@Transactional(propagation=Propagation.REQUIRES_NEW, isolation=Isolation.READ_COMMITTED)
public DBParent createChildForParent(long parentId) {
DBParent parent = parentDao.findById(parentId);
childService.createChildForParent(parentId);
parentDao.getSession().evict(parent);
parent = parentDao.findById(parentId);
return parent;
}