【问题标题】:Hibernate Session.delete() an object if existsHibernate Session.delete() 一个对象(如果存在)
【发布时间】:2011-08-12 04:15:08
【问题描述】:

Session类的JavaDoc中delete方法的描述是:

从数据存储中删除一个持久实例。该参数可以是与接收会话相关联的实例,也可以是具有与现有持久状态相关联的标识符的瞬态实例。

我的问题是:

  1. 我想删除一个分离对象,我可以用这个方法吗,AFAIK会话首先使一个对象从分离中持久化,然后执行它的操作。我对吗?
  2. 如果我不确定数据库中的对象是否存在,我应该使用 Session.get() 来检查它是否为空,然后执行删除操作,还是可以直接使用删除操作?

这是一个代码sn-p:

public void removeUnallocatedUserIfExits(final long itemId) {
    getHibernateTemplate().execute(new HibernateCallback() {

        public Object doInHibernate(Session session) throws HibernateException, SQLException {
            session.flush();
            session.setCacheMode(CacheMode.IGNORE);
            UnallocatedUser unallocatedUser;
            if ((unallocatedUser = (UnallocatedUser) session.get(UnallocatedUser.class, itemId)) != null) {
                session.delete(unallocatedUser);
            }
            session.flush();
            return null;
        }
    });
}

没事吧?

【问题讨论】:

    标签: java hibernate session


    【解决方案1】:

    Hibernate 原生查询示例如下。

    import org.hibernate.query.nativeQuery;  
    
    String sql = "Delete from Student where classId= :id"; 
    NativeQuery query = session.createNativeQuery(sql.toString()); 
    query.executeUpdate();
    

    【讨论】:

      【解决方案2】:

      或一个临时实例 与现有关联的标识符 持续状态

      这意味着您可以直接将您的entity 传递给session.delete(),以删除该对象。此外,您无需检查实体是否存在。如果在数据库中没有找到记录,应该有一个例外。事实上,我们通常不会真正得到这种情况。我们总是删除一个现有的实体,我的意思是通常的逻辑是这样的;所以,没有必要这样做。你可以这样做,

      SomeEntity ent = session.load(SomeEntity.class, '1234');
      session.delete(ent);
      

      或者你可以这样做,

      SomeEntity ent = new SomeEntity('1234'); // used constructor for brevity
      session.delete(ent);
      

      顺便说一句,你也可以使用这个版本session.delete(String query)

      sess.delete("from Employee e where e.id = '1234'"); // Just found it is deprecated
      

      【讨论】:

      • 您应该使用session.load() 而不是.get() 以避免获取实体的数据。
      • @GuillaumeF.,是的,那么您可能会得到一个代理实例。此外,该文档指出,“您不应使用load() 来确定实例是否存在(请改用get())。仅使用load() 来检索您假设存在的实例,其中不存在将是实际的错误”。这里我们假设实体存在;所以,是的,load() 将是首选。
      【解决方案3】:
      import org.hibernate.HibernateException;
      import org.hibernate.Session;
      import org.hibernate.SessionFactory;
      import org.hibernate.cfg.Configuration;
      
      public class DeletePersistentObjectWithHibernate {
      
      public static void main(String[] args) {
      
              SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
      
              Session session = sessionFactory.getCurrentSession();
      
              long id = 2;
      
              try {
                  session.beginTransaction();
      
                  Employee employee = (Employee) session.get(Employee.class, id);
      
                  session.delete(employee);
      
                  session.getTransaction().commit();
              }
              catch (HibernateException e) {
                  e.printStackTrace();
                  session.getTransaction().rollback();
              }
      
          }
      
      }
      

      【讨论】:

      • 请添加一些评论
      • session.get() 将从数据库中获取 Employee 对象。如果 Employee 对象包含另一个对象,那么该对象也将同时获取,然后 Employee 将通过 session.delete(obj) 从数据库中删除
      【解决方案4】:

      刚刚找到一个更好的解决方案:

      Query q = session.createQuery("delete Entity where id = X");
      q.executeUpdate();
      

      Hibernate Delete query

      【讨论】:

        【解决方案5】:

        你可以通过以下简单的hibernate轻松实现,

        Session session=getSession();  
        String hql = "delete from Student where classId= :id"; 
        session.createQuery(hql).setString("id", new Integer(id)).executeUpdate();
        

        【讨论】:

          【解决方案6】:

          试试这个...

          public <T> T delete(T t) throws Exception {
              try {
                  t = load(t);
                  session.delete(t);
                  session.flush();
              } catch (Exception e) {
                  throw e;
              } finally {
                  session.clear();
              }
          
              return t;
          }
          
          public <T> T load(T t) {
              session.buildLockRequest(LockOptions.NONE).lock(t);
              return t;
          }
          

          【讨论】:

            【解决方案7】:

            我想删除一个分离对象,我可以用这个方法吗,AFAIK session 首先使对象从分离中持久化,然后执行其 手术。我说的对吗?

            如果您知道要删除的对象的标识符,那么您可以创建一个设置了标识符的实例并将其传递给会话删除方法。此实例将被视为处于分离状态(因为有关联的标识符),但是它将在内部由 Hibernate 重新附加到会话,然后删除。

            如果我不确定数据库中是否存在对象,应该 我使用 Session.get() 检查它是否为空,然后 执行删除操作还是直接使用删除操作?

            如果找不到要删除的对象,delete 方法将抛出 StaleObjectException。因此,您可以使用异常处理来决定在这种情况下要做什么。

            【讨论】:

              猜你喜欢
              • 2014-08-30
              • 1970-01-01
              • 1970-01-01
              • 2022-11-19
              • 1970-01-01
              • 2021-05-16
              • 1970-01-01
              • 1970-01-01
              • 2019-09-01
              相关资源
              最近更新 更多