奇怪org.hibernate.LazyInitializationException JUNIT什么时候做
Weird org.hibernate.LazyInitializationException when do JUNIT
我正在为一个 SSH 项目做 JUnit。
首先,我在执行 @Test 方法时遇到了 org.hibernate.LazyInitializationException 。我做了一些研究并解决了它。
我所做的是添加用于绑定会话资源的 Setup 和 TearDown。
这2种方法是这样的:
@Before
public void setup(){
System.out.println("Setup() running....");
String filename = "WebContent\WEB-INF\classes\applicationContext.xml";
ctx = new FileSystemXmlApplicationContext(filename);
sf = (SessionFactory) ctx.getBean("sessionFactory");
Session s = sf.openSession();
TransactionSynchronizationManager.bindResource(sf, new SessionHolder(s));
}
@After
public void tearDown(){
System.out.println("TearDown() running....");
SessionHolder holder = (SessionHolder)TransactionSynchronizationManager.getResource(sf);
Session s = holder.getSession();
s.flush();
TransactionSynchronizationManager.unbindResource(sf);
SessionFactoryUtils.closeSession(s);
}
private SessionFactory sf;
private ApplicationContext ctx;
然后我又写了一个方法,但是这个异常又出现了!有点奇怪。我重新运行第一个测试方法,有效。但是第二个没有。
第一个测试方法是这样的:
@Test
public void testFindAll() {
UserGroupService userggroupService = (UserGroupService) ctx.getBean("UserGroupService");
try {
List groups = userggroupService.findAll();
System.out.println(groups);
if (groups != null){
for (Object grp : groups){
UserGroupBean group = (UserGroupBean) grp;
System.out.printf("id=%d, name=%s, %d members\n", group.getId(), group.getName(), group.getMembers()==null?0:group.getMembers().size());
if (group.getMembers() != null){
for(UserBean user: group.getMembers()){
System.out.printf("\tuser-%d, %s\n", user.getUserID(), user.getName());
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
第二种测试方法是这样的:
@Test
public void testDeleteRel() {
String filename = "WebContent\WEB-INF\classes\applicationContext.xml";
ApplicationContext ctx = new FileSystemXmlApplicationContext(filename);
UserGroupService service = (UserGroupService) ctx.getBean("UserGroupService");
try {
UserGroupBean userGroup = new UserGroupBean();
userGroup.setId(1L);
UserGroupBean group = (UserGroupBean) service.getUserGroup(userGroup);
List<UserBean> members = group.getMembers();
System.out.println(members.size()+" members");
// members.remove(0);
// service.updateUserGroup(group);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
采购订单代码如下:
@Entity
@Table(name = "UserGroupBean")
public class UserGroupBean implements UserGroup {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany(targetEntity = UserGroupBean.class,
cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
@JoinTable(name = "UserGroupParents", joinColumns = { @JoinColumn(name = "group_id") }, inverseJoinColumns = { @JoinColumn(name = "parent_id") })
//@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private List<UserGroupBean> parents;
@ManyToMany(targetEntity = UserBean.class,
cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
@JoinTable(name = "UserGroupMembers", joinColumns = { @JoinColumn(name = "group_id") }, inverseJoinColumns = { @JoinColumn(name = "user_id") })
//@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private List<UserBean> members;
// Getters and setters ...
我的问题是:为什么同样的@Before和@After代码,却只有一种方法可以运行好?我错过了什么?
谢谢
好吧,如果我理解了您的要求,在您的第二个测试方法中,您尝试再次初始化应用程序上下文,尽管它已在 before() 方法中初始化。这不是在 junit 中启动 spring 上下文的有效方法。参考那些可能解决你的例子是:
Spring Junit
要么
Spring Junit 2
对于错误 org.hibernate.LazyInitializationException 使用
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class TestAnything{
...
}
我正在为一个 SSH 项目做 JUnit。 首先,我在执行 @Test 方法时遇到了 org.hibernate.LazyInitializationException 。我做了一些研究并解决了它。 我所做的是添加用于绑定会话资源的 Setup 和 TearDown。
这2种方法是这样的:
@Before
public void setup(){
System.out.println("Setup() running....");
String filename = "WebContent\WEB-INF\classes\applicationContext.xml";
ctx = new FileSystemXmlApplicationContext(filename);
sf = (SessionFactory) ctx.getBean("sessionFactory");
Session s = sf.openSession();
TransactionSynchronizationManager.bindResource(sf, new SessionHolder(s));
}
@After
public void tearDown(){
System.out.println("TearDown() running....");
SessionHolder holder = (SessionHolder)TransactionSynchronizationManager.getResource(sf);
Session s = holder.getSession();
s.flush();
TransactionSynchronizationManager.unbindResource(sf);
SessionFactoryUtils.closeSession(s);
}
private SessionFactory sf;
private ApplicationContext ctx;
然后我又写了一个方法,但是这个异常又出现了!有点奇怪。我重新运行第一个测试方法,有效。但是第二个没有。
第一个测试方法是这样的:
@Test
public void testFindAll() {
UserGroupService userggroupService = (UserGroupService) ctx.getBean("UserGroupService");
try {
List groups = userggroupService.findAll();
System.out.println(groups);
if (groups != null){
for (Object grp : groups){
UserGroupBean group = (UserGroupBean) grp;
System.out.printf("id=%d, name=%s, %d members\n", group.getId(), group.getName(), group.getMembers()==null?0:group.getMembers().size());
if (group.getMembers() != null){
for(UserBean user: group.getMembers()){
System.out.printf("\tuser-%d, %s\n", user.getUserID(), user.getName());
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
第二种测试方法是这样的:
@Test
public void testDeleteRel() {
String filename = "WebContent\WEB-INF\classes\applicationContext.xml";
ApplicationContext ctx = new FileSystemXmlApplicationContext(filename);
UserGroupService service = (UserGroupService) ctx.getBean("UserGroupService");
try {
UserGroupBean userGroup = new UserGroupBean();
userGroup.setId(1L);
UserGroupBean group = (UserGroupBean) service.getUserGroup(userGroup);
List<UserBean> members = group.getMembers();
System.out.println(members.size()+" members");
// members.remove(0);
// service.updateUserGroup(group);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
采购订单代码如下:
@Entity
@Table(name = "UserGroupBean")
public class UserGroupBean implements UserGroup {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
@ManyToMany(targetEntity = UserGroupBean.class,
cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
@JoinTable(name = "UserGroupParents", joinColumns = { @JoinColumn(name = "group_id") }, inverseJoinColumns = { @JoinColumn(name = "parent_id") })
//@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private List<UserGroupBean> parents;
@ManyToMany(targetEntity = UserBean.class,
cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
@JoinTable(name = "UserGroupMembers", joinColumns = { @JoinColumn(name = "group_id") }, inverseJoinColumns = { @JoinColumn(name = "user_id") })
//@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private List<UserBean> members;
// Getters and setters ...
我的问题是:为什么同样的@Before和@After代码,却只有一种方法可以运行好?我错过了什么?
谢谢
好吧,如果我理解了您的要求,在您的第二个测试方法中,您尝试再次初始化应用程序上下文,尽管它已在 before() 方法中初始化。这不是在 junit 中启动 spring 上下文的有效方法。参考那些可能解决你的例子是: Spring Junit 要么 Spring Junit 2
对于错误 org.hibernate.LazyInitializationException 使用
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) @Transactional public class TestAnything{ ... }