使用Hibernate seesion.delete()的更好方法是-按ID删除还是按对象删除?

时间:2018-07-09 11:51:01

标签: spring hibernate spring-mvc spring-boot hibernate-session

我正在开发一个使用Spring MVC构建的应用程序,它使用Hibernate与数据存储进行交互。在尝试实现删除功能时,我发现有多种方法可以实现session.delete()。总的来说,我感到困惑的是,以下两种方法中的哪一种是实现Hibernate seesion.delete()的更好方法(更具体地说,是标准方法)。

由于该API调用在将来会变成微服务,我想这是从网络而非整个对象获取userId的标准方法。

方法1:

@Transactional    
public void deleteUser(User user) {
    sessionFactory.getCurrentSession().delete(user);
}

方法2:

@Transactional
public void deleteUser(int userId) {
    Query q = session.createQuery("delete User where id = :userId");
    query.setParameter("userId", userId);
    q.executeUpdate();
}

方法3:

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().get(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}

2 个答案:

答案 0 :(得分:3)

Gauillaume F.的答案有更多细节。我建议使用方法4(高效,可作为服务公开和Hibernate的惯用方式)。

方法1

@Transactional    
public void deleteUser(User user) {
    sessionFactory.getCurrentSession().delete(user);
}
  • 删除与会话缓存同步
  • user必须是Hibernate所控制的实例。因此,它不能直接作为服务公开。
  • 足够有效。首先取决于如何检索实例。

方法2

@Transactional
public void deleteUser(int userId) {
    Query q = session.createQuery("delete User where id = :userId");
    query.setParameter("userId", userId);
    q.executeUpdate();
}
  • 高效(没有实例从数据库加载或没有放入会话缓存)
  • 可以直接公开为服务
  • 未与会话缓存同步
  • 不必要地使用HQL

方法3

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().get(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}
  • 足够有效(实例首先从数据库中加载,放入会话缓存中,然后删除)
  • 可以直接公开为服务
  • 与会话缓存同步

方法4

@Transactional
public void deleteOrg(int userId) {
    User user = sessionFactory.getCurrentSession().load(User.class, userId);
    sessionFactory.getCurrentSession().delete(user);
}
  • 高效(不加载任何数据;将代理放入会话缓存中)
  • 可以直接公开为服务
  • 与会话缓存同步

答案 1 :(得分:2)

第二种方法不好,因为Hibernate不能告诉对象已被删除。它可能会在其内部会话缓存中产生问题。

第一种和第三种方法非常相似。您应该使用get(User.class, userId)来代替load(..),因为它返回一个代理对象而不是获取数据,所以它使用起来更快。