Commits

Bryan Turner committed 0fdbe21

Don't use Spring's Hibernate 3 support against 4.

- ResetableHiLoGeneratorHelper in the Hibernate 4 module was calling
the Hibernate 3 variant of SessionFactoryUtils
- Unfortunately, for Hibernate 4, SessionFactoryUtils has lost its
getSession(SessionFactory, boolean) convenience method
- Rewrote ResetableHiLoGeneratorHelper to use the new Hibernate 4
IsolationDelegate for its work
- This may not be correct, but I don't understand how this class is
used, and it has no documentation to help
- Additionally, if there is no current session, this version will
not create one, which doesn't match the old behaviour
- However, if the old version created one on the fly, it never closed
it, which is wrong, so I'm hoping that means there always is one
- Cleaned up imports and suppressed some warnings in the other versions
of ResetableHiLoGeneratorHelper, but did not modify them

  • Participants
  • Parent commits 07554f8

Comments (0)

Files changed (4)

atlassian-hibernate2-extras/src/main/java/com/atlassian/hibernate/extras/ResettableHiLoGeneratorHelper.java

 import net.sf.hibernate.SessionFactory;
 import net.sf.hibernate.engine.SessionFactoryImplementor;
 import net.sf.hibernate.id.IdentifierGenerator;
-import net.sf.hibernate.metadata.ClassMetadata;
 import net.sf.hibernate.persister.ClassPersister;
 import net.sf.hibernate.persister.EntityPersister;
 import org.slf4j.Logger;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
 /**
  * <p/>
  * A direct copy from version used in Bamboo
  */
+@SuppressWarnings("unused")
 public class ResettableHiLoGeneratorHelper
 {
     private static final Logger log = LoggerFactory.getLogger(ResettableHiLoGeneratorHelper.class);

atlassian-hibernate3-extras/src/main/java/com/atlassian/hibernate/extras/ResetableHiLoGeneratorHelper.java

  * This class is used to set the hibernate_unique_key.next_hi value to the high bits of the highest id in the DB, +1
  * after an import (for now) to maintain state in the database.
  */
+@SuppressWarnings({"deprecation", "unused"})
 public class ResetableHiLoGeneratorHelper
 {
     public static final String HIBERNATE_UNIQUE_KEY_COLUMN = "next_hi";

atlassian-hibernate3.6-extras/src/main/java/com/atlassian/hibernate/extras/ResetableHiLoGeneratorHelper.java

 import org.hibernate.persister.entity.SingleTableEntityPersister;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.support.JdbcUtils;
 import org.springframework.orm.hibernate3.SessionFactoryUtils;
 
 import java.sql.Connection;
  * This class is used to set the hibernate_unique_key.next_hi value to the high bits of the highest id in the DB, +1
  * after an import (for now) to maintain state in the database.
  */
+@SuppressWarnings({"deprecation", "unused"})
 public class ResetableHiLoGeneratorHelper
 {
     public static final String HIBERNATE_UNIQUE_KEY_COLUMN = "next_hi";

atlassian-hibernate4-extras/src/main/java/com/atlassian/hibernate/extras/ResetableHiLoGeneratorHelper.java

 package com.atlassian.hibernate.extras;
 
+import org.hibernate.JDBCException;
 import org.hibernate.Session;
 import org.hibernate.SessionFactory;
 import org.hibernate.engine.spi.SessionFactoryImplementor;
 import org.hibernate.engine.spi.SessionImplementor;
+import org.hibernate.jdbc.AbstractReturningWork;
+import org.hibernate.jdbc.AbstractWork;
+import org.hibernate.metadata.ClassMetadata;
 import org.hibernate.persister.entity.EntityPersister;
 import org.hibernate.persister.entity.SingleTableEntityPersister;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.support.JdbcUtils;
-import org.springframework.orm.hibernate3.SessionFactoryUtils;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
 /**
  * This class is used to set the hibernate_unique_key.next_hi value to the high bits of the highest id in the DB, +1
  * after an import (for now) to maintain state in the database.
+ * <p/>
+ * TODO: This entire class needs testing; it will not work like the versions for Hibernate 2.x or 3.x do.
  */
+@SuppressWarnings("unused")
 public class ResetableHiLoGeneratorHelper
 {
     public static final String HIBERNATE_UNIQUE_KEY_COLUMN = "next_hi";
      */
     public long getHiValue() throws SQLException
     {
-        long result = 0L;
-
-        Connection connection = null;
-        ResultSet resultSet = null;
-        Statement statement = null;
+        Session session = sessionFactory.getCurrentSession();
         try
         {
-            Session session = SessionFactoryUtils.getSession(sessionFactory, true);
-
-            connection = ((SessionImplementor) session).connection();
-            statement = connection.createStatement();
-            resultSet = statement.executeQuery("select " + HIBERNATE_UNIQUE_KEY_COLUMN + " from " + HIBERNATE_UNIQUE_KEY_TABLE);
-            if (resultSet.next())
-            {
-                result = resultSet.getLong(1); // might be null, but that's ok, will return 0;
-            }
+            return ((SessionImplementor) session).getTransactionCoordinator()
+                    .getTransaction()
+                    .createIsolationDelegate()
+                    .delegateWork(new NextHiGetter(), true);
         }
-        catch (SQLException e)
+        catch (JDBCException e)
         {
-            log.error("Error finding maximum next_hi value", e);
-            throw e;
+            log.error("Error finding maximum next_hi value", e.getSQLException());
+
+            throw e.getSQLException();
         }
-        finally
+    }
+
+    public void setNextHiValue(List<String> errors)
+    {
+        Session session = sessionFactory.getCurrentSession();
+        ((SessionImplementor) session).getTransactionCoordinator()
+                .getTransaction()
+                .createIsolationDelegate()
+                .delegateWork(new NextHiSetter(errors, sessionFactory), true);
+    }
+
+    public void setSessionFactory(SessionFactory sessionFactory)
+    {
+        this.sessionFactory = sessionFactory;
+    }
+
+    private static class NextHiGetter extends AbstractReturningWork<Long>
+    {
+        private static final String SQL = "select " + HIBERNATE_UNIQUE_KEY_COLUMN + " from " + HIBERNATE_UNIQUE_KEY_TABLE;
+
+        @Override
+        public Long execute(Connection connection) throws SQLException
         {
-            closeResultSet(resultSet);
-            closeStatement(statement);
-            commitConnection(connection);
+            ResultSet resultSet = null;
+            Statement statement = null;
+            try
+            {
+                statement = connection.createStatement();
+                resultSet = statement.executeQuery(SQL);
+                if (resultSet.next())
+                {
+                    return resultSet.getLong(1); // might be null, but that's ok, will return 0;
+                }
+            }
+            finally
+            {
+                closeResultSet(resultSet);
+                closeStatement(statement);
+            }
+
+            return 0L;
         }
-        return result;
     }
 
-    public void setNextHiValue(List<String> errors)
+    private static class NextHiSetter extends AbstractWork
     {
-        Connection connection = null;
-        Statement statement = null;
-        try
+        private final List<String> errors;
+        private final SessionFactoryImplementor sessionFactory;
+
+        private NextHiSetter(List<String> errors, SessionFactory sessionFactory)
         {
-            Session session = SessionFactoryUtils.getSession(sessionFactory, true);
-            Map<?, ?> metaDataMap = sessionFactory.getAllClassMetadata();
+            this.errors = errors;
+            this.sessionFactory = (SessionFactoryImplementor) sessionFactory;
+        }
 
-            connection = ((SessionImplementor) session).connection();
-            statement = connection.createStatement();
+        @Override
+        public void execute(Connection connection)
+        {
+            Map<String, ClassMetadata> metadataMap = sessionFactory.getAllClassMetadata();
 
-            long maximumId = 0;
-            int maxLo = 0;
-            for (Object o : metaDataMap.keySet())
+            Statement statement = null;
+            try
             {
-                String className = (String) o;
+                statement = connection.createStatement();
 
-                EntityPersister persister = ((SessionFactoryImplementor) sessionFactory).getEntityPersister(className);
-                if (persister instanceof SingleTableEntityPersister &&
-                        persister.getIdentifierGenerator() instanceof ResettableTableHiLoGenerator)
+                long maximumId = 0;
+                int maxLo = 0;
+                for (String className : metadataMap.keySet())
                 {
-                    SingleTableEntityPersister entityPersister = (SingleTableEntityPersister) persister;
-                    ResettableTableHiLoGenerator generator = (ResettableTableHiLoGenerator) persister.getIdentifierGenerator();
-
-                    // TODO need to work out why we have this logic.
-                    if (maxLo == 0)
+                    EntityPersister persister = sessionFactory.getEntityPersister(className);
+                    if (persister instanceof SingleTableEntityPersister &&
+                            persister.getIdentifierGenerator() instanceof ResettableTableHiLoGenerator)
                     {
-                        maxLo = generator.getMaxLo();
-                    }
-                    else if (maxLo != generator.getMaxLo())
-                    {
-                        //throw new UpgradeException("One generator uses " + maxLo + " for maxLo, generator for " +
-                        //        c.getName() + " uses " + generator.getMaxLo());
-                        errors.add("One generator uses " + maxLo + " for maxLo, generator for " +
-                                className + " uses " + generator.getMaxLo());
-                    }
+                        SingleTableEntityPersister entityPersister = (SingleTableEntityPersister) persister;
+                        ResettableTableHiLoGenerator generator = (ResettableTableHiLoGenerator) persister.getIdentifierGenerator();
 
-                    String[] idColumnNames = entityPersister.getIdentifierColumnNames();
-                    if (idColumnNames.length != 1)
-                    {
-                        errors.add("Expected a single ID column for " + className + " found " + idColumnNames.length);
-                    }
+                        // TODO need to work out why we have this logic.
+                        if (maxLo == 0)
+                        {
+                            maxLo = generator.getMaxLo();
+                        }
+                        else if (maxLo != generator.getMaxLo())
+                        {
+                            //throw new UpgradeException("One generator uses " + maxLo + " for maxLo, generator for " +
+                            //        c.getName() + " uses " + generator.getMaxLo());
+                            errors.add("One generator uses " + maxLo + " for maxLo, generator for " +
+                                    className + " uses " + generator.getMaxLo());
+                        }
 
-                    String sql = "select max(" + idColumnNames[0] + ") from " + entityPersister.getTableName();
-                    ResultSet resultSet = null;
-                    try
-                    {
-                        resultSet = statement.executeQuery(sql);
-                        if (!resultSet.next())
+                        String[] idColumnNames = entityPersister.getIdentifierColumnNames();
+                        if (idColumnNames.length != 1)
                         {
-                            errors.add("No maximum ID returned for " + className);
+                            errors.add("Expected a single ID column for " + className + " found " + idColumnNames.length);
                         }
-                        long value = resultSet.getLong(1); // might be null, but that's ok, will return 0;
-                        if (value > maximumId)
+
+                        String sql = "select max(" + idColumnNames[0] + ") from " + entityPersister.getTableName();
+                        ResultSet resultSet = null;
+                        try
                         {
-                            maximumId = value;
+                            resultSet = statement.executeQuery(sql);
+                            if (resultSet.next())
+                            {
+                                long value = resultSet.getLong(1); // might be null, but that's ok, will return 0;
+                                if (value > maximumId)
+                                {
+                                    maximumId = value;
+                                }
+                            }
+                            else
+                            {
+                                errors.add("No maximum ID returned for " + className);
+                            }
+                        }
+                        finally
+                        {
+                            closeResultSet(resultSet);
                         }
-                    }
-                    finally
-                    {
-                        closeResultSet(resultSet);
                     }
                 }
+
+                setNextHi(statement, (int) (maximumId / (maxLo + 1)) + 1);
+            }
+            catch (Exception e)
+            {
+                log.error("Error finding maximum next_hi value", e);
+                errors.add(e.getMessage());
+            }
+            finally
+            {
+                closeStatement(statement);
+                log.info("Completed database update: HiLoIdRepairUpgradeTask");
             }
-            int nextHi = (int) (maximumId / (maxLo + 1)) + 1;
+        }
+
+        private void setNextHi(Statement statement, int nextHi) throws SQLException
+        {
             log.info("Setting new next_hi to " + nextHi);
             if (statement.executeUpdate("update " + HIBERNATE_UNIQUE_KEY_TABLE + " set " + HIBERNATE_UNIQUE_KEY_COLUMN + " = " + nextHi) == 0)
             {
                 }
             }
         }
-        catch (Exception e)
-        {
-            log.error("Error finding maximum next_hi value", e);
-            errors.add(e.getMessage());
-        }
-        finally
-        {
-            closeStatement(statement);
-            commitConnection(connection);
-            log.info("Completed database update: HiLoIdRepairUpgradeTask");
-        }
-    }
-
-    public void setSessionFactory(SessionFactory sessionFactory)
-    {
-        this.sessionFactory = sessionFactory;
-    }
-
-    private static void commitConnection(Connection connection)
-    {
-        if (connection != null)
-        {
-            try
-            {
-                connection.commit();
-            }
-            catch (SQLException e)
-            {
-                // A little late now to do anything
-            }
-        }
     }
 }