哪个是使用 Hibernate seesion.delete() 的更好方法 - 按 Id 删除或按对象删除?
Which is the better way of using Hibernate seesion.delete() - Delete by Id or delete by object?
我正在开发一个使用 Spring MVC 构建的应用程序,它使用 Hibernate 与数据存储交互。当我尝试实现删除功能时,我发现有多种方法可以实现 session.delete()。总之,我很困惑以下两种方法中哪一种是实现 Hibernate seesion.delete().
的更好方法(更具体地说,是标准方法)
由于这个 API 调用在未来阶段会变成微服务,我想这是从网络而不是整个对象获取 userId 的标准方法。
方法一:
@Transactional
public void deleteUser(User user) {
sessionFactory.getCurrentSession().delete(user);
}
方法二:
@Transactional
public void deleteUser(int userId) {
Query q = session.createQuery("delete User where id = :userId");
query.setParameter("userId", userId);
q.executeUpdate();
}
方法三:
@Transactional
public void deleteOrg(int userId) {
User user = sessionFactory.getCurrentSession().get(User.class, userId);
sessionFactory.getCurrentSession().delete(user);
}
第二种方法不好,因为Hibernate 无法判断对象已被删除;它可能会导致其内部会话缓存出现问题。
第一种和第三种方法很相似。您应该使用 load(..)
而不是 get(User.class, userId)
,因为它 returns 是一个代理对象而不是获取数据。
Gauillaume F. 回答的更多细节。我建议使用方法 4(高效、可公开的服务和 Hibernate 的惯用用法)。
方法一
@Transactional
public void deleteUser(User user) {
sessionFactory.getCurrentSession().delete(user);
}
- 删除与会话缓存同步
user
必须是 Hibernate 控制下的一个实例。所以不能直接暴露为服务
- 足够高效。这取决于首先如何检索实例。
方法二
@Transactional
public void deleteUser(int userId) {
Query q = session.createQuery("delete User where id = :userId");
query.setParameter("userId", userId);
q.executeUpdate();
}
- 高效(没有实例从数据库加载或放入会话缓存)
- 可以直接暴露为服务
- 未与会话缓存同步
- 不必要地使用 HQL
方法三
@Transactional
public void deleteOrg(int userId) {
User user = sessionFactory.getCurrentSession().get(User.class, userId);
sessionFactory.getCurrentSession().delete(user);
}
- 足够高效(实例首先从数据库加载,放入会话缓存,然后删除)
- 可以直接暴露为服务
- 与会话缓存同步
方法四
@Transactional
public void deleteOrg(int userId) {
User user = sessionFactory.getCurrentSession().load(User.class, userId);
sessionFactory.getCurrentSession().delete(user);
}
- 高效(不加载数据;而是将代理放入会话缓存)
- 可以直接暴露为服务
- 与会话缓存同步
我正在开发一个使用 Spring MVC 构建的应用程序,它使用 Hibernate 与数据存储交互。当我尝试实现删除功能时,我发现有多种方法可以实现 session.delete()。总之,我很困惑以下两种方法中哪一种是实现 Hibernate seesion.delete().
的更好方法(更具体地说,是标准方法)由于这个 API 调用在未来阶段会变成微服务,我想这是从网络而不是整个对象获取 userId 的标准方法。
方法一:
@Transactional
public void deleteUser(User user) {
sessionFactory.getCurrentSession().delete(user);
}
方法二:
@Transactional
public void deleteUser(int userId) {
Query q = session.createQuery("delete User where id = :userId");
query.setParameter("userId", userId);
q.executeUpdate();
}
方法三:
@Transactional
public void deleteOrg(int userId) {
User user = sessionFactory.getCurrentSession().get(User.class, userId);
sessionFactory.getCurrentSession().delete(user);
}
第二种方法不好,因为Hibernate 无法判断对象已被删除;它可能会导致其内部会话缓存出现问题。
第一种和第三种方法很相似。您应该使用 load(..)
而不是 get(User.class, userId)
,因为它 returns 是一个代理对象而不是获取数据。
Gauillaume F. 回答的更多细节。我建议使用方法 4(高效、可公开的服务和 Hibernate 的惯用用法)。
方法一
@Transactional
public void deleteUser(User user) {
sessionFactory.getCurrentSession().delete(user);
}
- 删除与会话缓存同步
user
必须是 Hibernate 控制下的一个实例。所以不能直接暴露为服务- 足够高效。这取决于首先如何检索实例。
方法二
@Transactional
public void deleteUser(int userId) {
Query q = session.createQuery("delete User where id = :userId");
query.setParameter("userId", userId);
q.executeUpdate();
}
- 高效(没有实例从数据库加载或放入会话缓存)
- 可以直接暴露为服务
- 未与会话缓存同步
- 不必要地使用 HQL
方法三
@Transactional
public void deleteOrg(int userId) {
User user = sessionFactory.getCurrentSession().get(User.class, userId);
sessionFactory.getCurrentSession().delete(user);
}
- 足够高效(实例首先从数据库加载,放入会话缓存,然后删除)
- 可以直接暴露为服务
- 与会话缓存同步
方法四
@Transactional
public void deleteOrg(int userId) {
User user = sessionFactory.getCurrentSession().load(User.class, userId);
sessionFactory.getCurrentSession().delete(user);
}
- 高效(不加载数据;而是将代理放入会话缓存)
- 可以直接暴露为服务
- 与会话缓存同步