Hibernate合并不插入数据?

时间:2014-04-11 19:04:39

标签: spring hibernate

您好我尝试使用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数据

1 个答案:

答案 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,

  1. 除非您实际获得MergeConflict异常,否则不要使用merge(即使这样,它很可能是您实际需要使用合并的程序逻辑错误)。

  2. 您不需要从saveOrUpdate方法返回对象,一旦保存完成,Hibernate将自动更新对象的ID。

  3. 您不应该使用SessionFactory打开会话,您应该获得在单元测试中由@Transactional注释创建的当前运行会话的实例。