【发布时间】:2012-11-14 10:07:57
【问题描述】:
在问这个问题之前,这里是我的问题的背景:
我有一个名为“Category”的特定实体,它有一个属性 Category(父级)和另一个类型为“relatedEntity”的属性。
以下是代码示例:
@Entity
public class Category {
...
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="entityID")
private RelatedEntity entity;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="parentID")
private Category parent;
...
}
因此,如您所见,我为这些属性声明了 ManyToOne 关系,并且还声明了延迟加载获取策略。
现在,我在 DAO 对象中使用此方法来获取类别列表:
public List<Category> getAll() {
Criteria crit = sessionFactory.getCurrentSession().createCriteria(Category.class);
return (crit.list());
}
我得到了一个调用 DAO 方法的特定服务对象:
@Transactional(readOnly = true)
public List<Category> getAllCategories() {
return (categoryDAO.getAll());
}
目前没有什么特别的...现在,我的单元测试来了:
@Test
public void testCategories() {
List<Category> cat = service.getAllCategories();
assertNotNull(cat);
assertFalse(cat.isEmpty());
for (Category c : cat) {
try {
assertNotNull(c.getEntity().getName());
fail("Expected lazy init. on Category.Entity");
}
catch(LazyInitializationException ex) {
//Exception is caught
}
try {
assertNotNull(c.getParent().getName());
//No exception
fail("Expected lazy init. on Category.Parent");
}
catch(LazyInitializationException ex) {}
}
}
运行测试后,在第一个 try/catch 块中捕获了一个异常,并触发了第二个失败,说明该类别的父属性上没有 LazyInitException。
所以我可以打电话
c.getParent().getParent().getName();
或
c.getParent().getParent().getParent().getName()
没有任何异常被引发。
我在我的配置文件中设置了'show_sql=true',在调用父属性的getter后,我在日志中看不到任何补充请求,所以没有新请求,但加载了父属性。
谁能解释一下为什么父属性不懒惰?
编辑:
我已经更新了我的测试用例。
@Test(expected=LazyInitializationException.class)
public void lazyCategoriesParentsList() {
List<Category> cat = service.getAllCategories();
assertNotNull(cat);
assertFalse(cat.isEmpty());
for (Category c : cat) {
assertNotNull(c.getParent().getName());
}
}
现在测试通过了...是否与我之前的测试用例中实体属性的访问(通过 c.getEntity())有关?
【问题讨论】:
-
您应该不在单元测试中捕获异常并手动失败(或者在没有抛出异常时失败,如您的情况),您应该使用 @ 传播预期的异常987654328@.
标签: java hibernate unit-testing jpa lazy-loading