您好我尝试使用hibernate 4.x和spring 4.x插入数据,这是我的代码
@RunWith(SpringJUnit4ClassRunner.class)
//ApplicationContext will be loaded from "classpath:/app-config.xml"
@ContextConfiguration("/applicationContext.xml")
@ActiveProfiles("dev")
@Transactional
public class UserDAOTest {
@Autowired
private UserDAO userDAOImpl;
@Rollback(false)
@Test
public void testSave()
{
System.out.println(userDAOImpl);
User user =new User();
//User us=userDAOImpl.get(1);
User us=userDAOImpl.save(new User("anil", "a@gmail.com", "9505485444", "56482", null, null));
//userDAOImpl.saveOrUpdate(new User("anil", "a@gmail.com", "9505485444", "56482", null, null));
System.out.println(us.getUserId());
}
}
这是保存方法
public E save(E object) {
return (E)getCurrentSession().merge(object);
}
和gessionmethod是
public Session getCurrentSession() {
return sessionFactory.openSession();
}
如果我使用saveOrUpdate而不是merge,它工作正常,为什么合并失败?
但如果我改变我的保存方法,如下所示
public E save(E object) {
// return (E)getCurrentSession().saveOrUpdate(object);.merge(object);
Session session = getCurrentSession();
session.saveOrUpdate(object);
return (E) session.merge(object);
}
与数据库
具有syn数据答案 0 :(得分:1)
首先,您不应该打开会话,因为您正在使用@Transactional,因此应该为您创建会话。如果由于没有会话而收到异常,则说明您的事务管理配置不正确。您应该使用sessionFactory.getCurrentSession();
其次,session.merge()
方法具有非常特定的上下文。如果你的会话中有一个持久对象的2个活动版本,你应该只使用合并,并且你希望hibernate自动组合它们并保存结果。这不是这种情况。您有一个活动版本的持久对象,因此您应该在上面的方法中调用session.createOrUpdate();
。
第三,将对象从save方法中退出是没有意义的,因为Hibernate应该自动为你做这件事。像这样重构你的DAO:
public void saveOrUpdate(E object){
getCurrentSession().saveOrUpdate(object)
}
您的单元测试应如下所示:
@Test
public void testDaoSave(){
User user = new User("anil", "a@gmail.com", "9505485444", "56482", null, null);
userDaoImpl.saveOrUpdate(user);
System.out.println("User ID: " + user.getUserId()
}
Hibernate将在使用反射和AOP切入点的组合调用保存后自动更新对象的ID。
TL; DR,
除非您实际获得MergeConflict异常,否则不要使用merge(即使这样,它很可能是您实际需要使用合并的程序逻辑错误)。
您不需要从saveOrUpdate方法返回对象,一旦保存完成,Hibernate将自动更新对象的ID。
您不应该使用SessionFactory打开会话,您应该获得在单元测试中由@Transactional注释创建的当前运行会话的实例。