package northwind.service; import java.io.Serializable; import org.hibernate.HibernateException; import org.hibernate.cache.spi.access.EntityRegionAccessStrategy; import org.hibernate.cache.spi.access.NaturalIdRegionAccessStrategy; import org.hibernate.engine.spi.Mapping; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.mapping.PersistentClass; import org.hibernate.metamodel.binding.EntityBinding; import org.hibernate.persister.entity.SingleTableEntityPersister; /** * Allows use of null version column by modifying the SQL during updates and deletes. * Don't use this if you can make your version column not-null. */ public class NullableVersionEntityPersister extends SingleTableEntityPersister { public NullableVersionEntityPersister(EntityBinding entityBinding, EntityRegionAccessStrategy cacheAccessStrategy, NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, SessionFactoryImplementor factory, Mapping mapping) throws HibernateException { super(entityBinding, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory, mapping); } public NullableVersionEntityPersister(PersistentClass persistentClass, EntityRegionAccessStrategy cacheAccessStrategy, NaturalIdRegionAccessStrategy naturalIdRegionAccessStrategy, SessionFactoryImplementor factory, Mapping mapping) throws HibernateException { super(persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, factory, mapping); } /** * Handle null oldVersion values by modifying the sql */ @Override protected boolean update(Serializable id, Object[] fields, Object[] oldFields, Object rowId, boolean[] includeProperty, int j, Object oldVersion, Object object, String sql, SessionImplementor session) throws HibernateException { if (oldVersion == null) { sql = replaceVersionClause(sql); } return super.update(id, fields, oldFields, rowId, includeProperty, j, oldVersion, object, sql, session); } /** * Handle null version values by modifying the sql */ @Override protected void delete(Serializable id, Object version, int j, Object object, String sql, SessionImplementor session, Object[] loadedState) throws HibernateException { if (version == null) { sql = replaceVersionClause(sql); } super.delete(id, version, j, object, sql, session, loadedState); } /** * Make the sql say "(rowVersion=? or rowVersion is null)" instead of "rowVersion=?" */ protected String replaceVersionClause(String sql) { String vname = this.getVersionColumnName(); int where = sql.toLowerCase().indexOf("where"); String whereClause = sql.substring(where); String orig = vname + "=?"; String repl = '(' + orig + " or " + vname + " is null)"; whereClause = whereClause.replace(orig, repl); sql = sql.substring(0, where) + whereClause; return sql; } }