使用Hibernate Session.doWork生成序列ID

时间:2012-05-24 11:09:13

标签: java hibernate connection prepared-statement

Hibernate Session'doWork()方法可直接访问java.sql.Connection

以下是创建和执行PreparedStatement以生成序列

的方法之一
public Long generateId() {
    final Long id[] = { null };

    getSessionFactory().openSession().doWork(new Work() {
        public void execute(Connection connection) throws SQLException {
            PreparedStatement ps = connection
                    .prepareStatement("SELECT HIB_SEQ.nextval FROM DUAL");
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                id[0] = rs.getLong(0);
            }
        }
    });
    return id[0];
}

首先,有更好的方法吗?

第二个Q我们是否需要明确关闭上面创建的PreparedStatement

3 个答案:

答案 0 :(得分:0)

    String query = ((SessionFactoryImplementor)sessionFactory).getDialect().getSequenceNextValString(seqName);
    Session session = sessionFactory.getCurrentSession();
    return (Long) session.createSQLQuery(query).addScalar("nextval", Hibernate.LONG).uniqueResult();

您可能需要稍微调整标量部分以适合数据库的列名和返回类型。

答案 1 :(得分:0)

PreparedStatement的一个实例是作为方法Work.execute的一部分创建的,因此应该在该范围内处理,包括关闭(一旦从变量{方法完成其执行,一个实例本身将由GC收集{1}}将超出范围,但任何外部资源(如开放游标)都需要显式调用ps)。

另一方面,ps.close()的一个实例被Hibernate传递给方法,不应该手动关闭 - 这是Hibernate的责任。

答案 2 :(得分:0)

1)对于返回值,我们可以使用doReturningWork

public int updateEmployeeStatusWithCount(final List<String> employeeList) throws DBException
{
       Session session = null;
       try
       {
              session = HibernateUtil.getSession();
              session.beginTransaction();
              int cnt = session.doReturningWork(new ReturningWork<Integer>() {
                     @Override
                     public Integer execute(Connection conn) throws SQLException {
                           PreparedStatement pStmt = null;
                           try
                           {
                                  int updatedCnt = 0;
                                  String sqlQry = "UPDATE EMP_DETAILS set IS_ACTIVE='N' WHERE EMP_ID=?";
                                  pStmt = conn.prepareStatement(sqlQry);
                                  for(String empId:employeeList)
                                  {
                                         System.out.println(empId);
                                         pStmt.setString(1, empId);
                                         int cnt = pStmt.executeUpdate();
                                         updatedCnt+=cnt;
                                  }
                                  return updatedCnt;
                           }
                           finally
                           {
                                  pStmt.close();
                           }                                
                     }
              });
              session.getTransaction().commit();
              return cnt;
       }
       catch(HibernateException e)
       {
              throw new DBException("Error occured while updating Employee Status",e);
       }
       finally
       {
              HibernateUtil.closeSession(session);
       }            
}

2)是的我们必须明确关闭PreparedStatement 见下面的例子

public void updateEmployeeStatus(final List<String> employeeList) throws DBException
{
       Session session = null;
       try
       {
              session = HibernateUtil.getSession();
              session.beginTransaction();
              session.doWork(new Work() {
                     @Override
                     public void execute(Connection conn) throws SQLException {
                           PreparedStatement pStmt = null;
                           try
                           {
                                  String sqlQry = "UPDATE EMP_DETAILS set IS_ACTIVE='N' WHERE EMP_ID=?";
                                  pStmt = conn.prepareStatement(sqlQry);
                                  for(String empId:employeeList)
                                  {
                                         pStmt.setString(1, empId);
                                         pStmt.addBatch();
                                  }
                                  pStmt.executeBatch();
                           }
                           finally
                           {
                                  pStmt.close();
                           }                                
                     }
              });
              session.getTransaction().commit();
       }
       catch(HibernateException e)
       {
              throw new DBException("Error occured while updating Employee Status",e);
       }
       finally
       {
              HibernateUtil.closeSession(session);
       }            
}

Reference