get next sequence value from database using hibernate
You can use Hibernate Dialect API for Database independence as follow
class SequenceValueGetter { private SessionFactory sessionFactory; // For Hibernate 3 public Long getId(final String sequenceName) { final List<Long> ids = new ArrayList<Long>(1); sessionFactory.getCurrentSession().doWork(new Work() { public void execute(Connection connection) throws SQLException { DialectResolver dialectResolver = new StandardDialectResolver(); Dialect dialect = dialectResolver.resolveDialect(connection.getMetaData()); PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement( dialect.getSequenceNextValString(sequenceName)); resultSet = preparedStatement.executeQuery(); resultSet.next(); ids.add(resultSet.getLong(1)); }catch (SQLException e) { throw e; } finally { if(preparedStatement != null) { preparedStatement.close(); } if(resultSet != null) { resultSet.close(); } } } }); return ids.get(0); } // For Hibernate 4 public Long getID(final String sequenceName) { ReturningWork<Long> maxReturningWork = new ReturningWork<Long>() { @Override public Long execute(Connection connection) throws SQLException { DialectResolver dialectResolver = new StandardDialectResolver(); Dialect dialect = dialectResolver.resolveDialect(connection.getMetaData()); PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement( dialect.getSequenceNextValString(sequenceName)); resultSet = preparedStatement.executeQuery(); resultSet.next(); return resultSet.getLong(1); }catch (SQLException e) { throw e; } finally { if(preparedStatement != null) { preparedStatement.close(); } if(resultSet != null) { resultSet.close(); } } } }; Long maxRecord = sessionFactory.getCurrentSession().doReturningWork(maxReturningWork); return maxRecord; }}
Here is what worked for me (specific to Oracle, but using scalar
seems to be the key)
Long getNext() { Query query = session.createSQLQuery("select MYSEQ.nextval as num from dual") .addScalar("num", StandardBasicTypes.BIG_INTEGER); return ((BigInteger) query.uniqueResult()).longValue();}
Thanks to the posters here: springsource_forum
I found the solution:
public class DefaultPostgresKeyServer{ private Session session; private Iterator<BigInteger> iter; private long batchSize; public DefaultPostgresKeyServer (Session sess, long batchFetchSize) { this.session=sess; batchSize = batchFetchSize; iter = Collections.<BigInteger>emptyList().iterator(); } @SuppressWarnings("unchecked") public Long getNextKey() { if ( ! iter.hasNext() ) { Query query = session.createSQLQuery( "SELECT nextval( 'mySchema.mySequence' ) FROM generate_series( 1, " + batchSize + " )" ); iter = (Iterator<BigInteger>) query.list().iterator(); } return iter.next().longValue() ; }}