This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch 8.0.x-hibernate7-dev
in repository https://gitbox.apache.org/repos/asf/grails-core.git


The following commit(s) were added to refs/heads/8.0.x-hibernate7-dev by this 
push:
     new 9312d2ab30 dbmigration: added specs for Generators
9312d2ab30 is described below

commit 9312d2ab30a939a4df0ce51a7901991187e62f3b
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Wed Mar 11 17:14:35 2026 -0500

    dbmigration: added specs for Generators
---
 grails-data-hibernate7/dbmigration/ISSUES.md       |  41 -----
 .../database/HibernateClassicDatabase.java         |  23 ++-
 .../ext/hibernate/database/HibernateDatabase.java  |  53 +++---
 .../database/HibernateSpringBeanDatabase.java      |  82 +++++-----
 .../database/HibernateSpringPackageDatabase.java   | 142 ++++++++--------
 .../hibernate/database/NoOpConnectionProvider.java |  33 +++-
 .../NoOpMultiTenantConnectionProvider.java         |  29 +++-
 .../database/connection/HibernateConnection.java   |  72 +++++++--
 .../connection/HibernateConnectionMetadata.java    | 178 ++++++++++++++++++++-
 .../database/connection/HibernateDriver.java       |   8 +-
 .../diff/ChangedForeignKeyChangeGenerator.java     |   2 +-
 .../diff/ChangedPrimaryKeyChangeGenerator.java     |   2 +-
 .../diff/ChangedSequenceChangeGenerator.java       |  12 +-
 .../ChangedUniqueConstraintChangeGenerator.java    |   2 +-
 .../diff/MissingSequenceChangeGenerator.java       |   4 +-
 .../diff/UnexpectedIndexChangeGenerator.java       |   2 +-
 .../snapshot/ColumnSnapshotGenerator.java          |  15 +-
 .../snapshot/HibernateSnapshotGenerator.java       |  41 +++--
 .../hibernate/snapshot/IndexSnapshotGenerator.java |   9 +-
 .../snapshot/SequenceSnapshotGenerator.java        |   4 +-
 .../hibernate/snapshot/TableSnapshotGenerator.java |   4 +-
 .../UniqueConstraintSnapshotGenerator.java         |  23 ++-
 22 files changed, 525 insertions(+), 256 deletions(-)

diff --git a/grails-data-hibernate7/dbmigration/ISSUES.md 
b/grails-data-hibernate7/dbmigration/ISSUES.md
deleted file mode 100644
index 873d73651e..0000000000
--- a/grails-data-hibernate7/dbmigration/ISSUES.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Database Migration Issues (Hibernate 7)
-
-This document tracks technical challenges, API incompatibilities, and known 
test failures discovered during the development of the 
`grails-data-hibernate7-dbmigration` module.
-
----
-
-## ✅ RESOLVED
-
-### Snapshot Generator Specs — GORM Entity Recognition
-- **Affected Tests:** `ForeignKeySnapshotGeneratorSpec`, 
`PrimaryKeySnapshotGeneratorSpec`, `TableSnapshotGeneratorSpec`, 
`IndexSnapshotGeneratorSpec`, `UniqueConstraintSnapshotGeneratorSpec`, 
`SequenceSnapshotGeneratorSpec`
-- **Root Cause:** `HibernateMappingContext.createPersistentEntity()` only 
creates persistent entities for classes where 
`GormEntity.class.isAssignableFrom(javaClass)`. The original test entities were 
plain Java/Groovy classes annotated with `@jakarta.persistence.Entity`, which 
are silently skipped by GORM — resulting in empty Hibernate metadata (no table 
mappings).
-- **Fix:** Replaced all inner-static-class entities (Jakarta `@Entity`) and 
`com.example.ejb3.auction` Java imports with top-level GORM 
`@grails.gorm.annotation.Entity` classes defined in the same `.groovy` spec 
file. All 6 tests now pass.
-
-### Envers Initialization
-- **Issue:** `org.hibernate.HibernateException: Expecting EnversService to 
have been initialized prior to call to EnversIntegrator#integrate`.
-- **Fix:** Explicitly disabled Envers in test config: 
`hibernate.integration.envers.enabled: false`.
-
----
-
-### `TableGeneratorSnapshotGeneratorSpec` — Real GORM Entity via 
`HibernateSnapshotIntegrationSpec`
-- **Issue:** `TableGenerator.getTableName()` in Hibernate 7 is not 
interceptable by Spock's `Stub()`/`GroovyStub()` — the method accesses 
`this.qualifiedTableName` which is only set after `configure()` + 
`registerExportables()`. `BasicValue.getGenerator()` was also removed in 
Hibernate 7, breaking the original approach.
-- **Fix:** Extended `HibernateSnapshotIntegrationSpec`, added a top-level GORM 
`@Entity TableGeneratorEntity` with `id generator: 'table'`, and retrieved the 
real `GrailsTableGenerator` via 
`datastore.sessionFactory.getMappingMetamodel().getEntityDescriptor(TableGeneratorEntity.name).getGenerator()`.
 Assertions use `tableGenerator.getTableName()` / 
`tableGenerator.getSegmentColumnName()` / `tableGenerator.getValueColumnName()` 
so they remain correct regardless of default param values.
-
----
-
-## ℹ️ BACKGROUND / OTHER NOTES
-
-### `BasicValue.getGenerator()` Removal (Hibernate 7)
-- `org.hibernate.mapping.BasicValue.getGenerator()` was removed in Hibernate 7.
-- Any code that previously extracted a generator from mapping metadata this 
way must be rewritten using `createGenerator(Dialect, RootClass, ...)` or by 
iterating namespace exportables.
-
-### `JdbcDatabaseSnapshot` Constructor
-- Liquibase 4.x requires `JdbcDatabaseSnapshot(DatabaseObject[] examples, 
Database database)`. Tests use the correct constructor.
-
-### Testcontainers / Docker Dependency
-- Integration tests require Docker (PostgreSQL container). Tests use 
`@Requires({ isDockerAvailable() })` to skip when Docker is absent.
-- Checks both `~/.docker/run/docker.sock` and `/var/run/docker.sock`.
-
-### `GormDatabase` Service Loading
-- Liquibase's `DatabaseFactory` tries to instantiate all registered `Database` 
implementations via no-arg constructor. `GormDatabase` requires a 
`HibernateDatastore`, so service-loader registration may cause issues in CLI 
contexts. Worked around in tests by manual instantiation.
-
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateClassicDatabase.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateClassicDatabase.java
index 314c3c0302..37db900383 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateClassicDatabase.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateClassicDatabase.java
@@ -11,6 +11,7 @@ import org.hibernate.cfg.Configuration;
 import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
 import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
 import org.hibernate.service.ServiceRegistry;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
 
 /**
  * Database implementation for "classic" hibernate configurations.
@@ -18,6 +19,8 @@ import org.hibernate.service.ServiceRegistry;
 public class HibernateClassicDatabase extends HibernateDatabase {
 
     protected Configuration configuration;
+    // Track the registry so we can close it later
+    private ServiceRegistry serviceRegistry;
 
     @Override
     public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) {
@@ -53,14 +56,28 @@ public class HibernateClassicDatabase extends 
HibernateDatabase {
         
config.setProperty(HibernateDatabase.HIBERNATE_TEMP_USE_JDBC_METADATA_DEFAULTS, 
Boolean.FALSE.toString());
         config.setProperty("hibernate.cache.use_second_level_cache", "false");
 
-        ServiceRegistry standardRegistry = configuration
+        // Assign to the class field instead of a local variable
+        this.serviceRegistry = configuration
                 .getStandardServiceRegistryBuilder()
                 .applySettings(config.getProperties())
                 .addService(ConnectionProvider.class, new 
NoOpConnectionProvider())
                 .addService(MultiTenantConnectionProvider.class, new 
NoOpMultiTenantConnectionProvider())
                 .build();
 
-        config.buildSessionFactory(standardRegistry);
+        // We build the factory to finalize the configuration, but we don't
+        // need to hold a reference to it here if we aren't using it.
+        config.buildSessionFactory(serviceRegistry);
+    }
+
+    @Override
+    public void close() throws DatabaseException {
+        try {
+            if (serviceRegistry != null) {
+                StandardServiceRegistryBuilder.destroy(serviceRegistry);
+            }
+        } finally {
+            super.close();
+        }
     }
 
     @Override
@@ -72,4 +89,4 @@ public class HibernateClassicDatabase extends 
HibernateDatabase {
     protected String getDefaultDatabaseProductName() {
         return "Hibernate Classic";
     }
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateDatabase.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateDatabase.java
index 37e3506401..3bbc9c53c9 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateDatabase.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateDatabase.java
@@ -42,14 +42,17 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
         setDefaultSchemaName(DEFAULT_SCHEMA);
     }
 
+    @Override
     public boolean requiresPassword() {
         return false;
     }
 
+    @Override
     public boolean requiresUsername() {
         return false;
     }
 
+    @Override
     public String getDefaultDriver(String url) {
         if (url.startsWith("hibernate")) {
             return HibernateDriver.class.getName();
@@ -57,6 +60,7 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
         return null;
     }
 
+    @Override
     public int getPriority() {
         return PRIORITY_DEFAULT;
     }
@@ -130,21 +134,25 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
         String path = getHibernateConnection().getPath();
         if (!path.contains("/")) {
             try {
-                Class<?> clazz = 
Thread.currentThread().getContextClassLoader().loadClass(path);
+                // Fix: Use Thread Context ClassLoader for J2EE/Spring 
compliance (PMD #7)
+                ClassLoader contextClassLoader = 
Thread.currentThread().getContextClassLoader();
+                Class<?> clazz = contextClassLoader.loadClass(path);
+
                 if (CustomMetadataFactory.class.isAssignableFrom(clazz)) {
                     try {
                         return ((CustomMetadataFactory)
-                                        
clazz.getDeclaredConstructor().newInstance())
+                                clazz.getDeclaredConstructor().newInstance())
                                 .getMetadata(this, getHibernateConnection());
                     } catch (InstantiationException
-                            | IllegalAccessException
-                            | InvocationTargetException
-                            | NoSuchMethodException e) {
+                             | IllegalAccessException
+                             | InvocationTargetException
+                             | NoSuchMethodException e) {
                         throw new DatabaseException(e);
                     }
                 }
             } catch (ClassNotFoundException ignore) {
-                // not really a class, continue
+                // Fix: Avoid empty catch blocks by documenting the intent 
(PMD #6)
+                Scope.getCurrentScope().getLog(getClass()).debug("Path " + 
path + " is not a CustomMetadataFactory, continuing with standard build.");
             }
         }
 
@@ -167,12 +175,13 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
         AtomicReference<Metadata> result = new AtomicReference<>();
 
         Thread t = new Thread(() -> result.set(metadataBuilder.build()));
-        t.setContextClassLoader(Scope.getCurrentScope().getClassLoader());
+        
t.setContextClassLoader(Thread.currentThread().getContextClassLoader());
         t.setUncaughtExceptionHandler((_t, e) -> thrownException.set(e));
         t.start();
         try {
             t.join();
         } catch (InterruptedException e) {
+            Thread.currentThread().interrupt(); // Restore interrupted status
             throw new DatabaseException(e);
         }
         Throwable thrown = thrownException.get();
@@ -197,10 +206,10 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
                         .newInstance();
                 Scope.getCurrentScope().getLog(getClass()).info("Using dialect 
" + dialectString);
             } catch (InstantiationException
-                    | IllegalAccessException
-                    | InvocationTargetException
-                    | NoSuchMethodException
-                    | ClassNotFoundException e) {
+                     | IllegalAccessException
+                     | InvocationTargetException
+                     | NoSuchMethodException
+                     | ClassNotFoundException e) {
                 throw new DatabaseException(e);
             }
         } else {
@@ -241,10 +250,10 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
                         .newInstance());
             }
         } catch (InstantiationException
-                | IllegalAccessException
-                | InvocationTargetException
-                | NoSuchMethodException
-                | ClassNotFoundException e) {
+                 | IllegalAccessException
+                 | InvocationTargetException
+                 | NoSuchMethodException
+                 | ClassNotFoundException e) {
             throw new DatabaseException(e);
         }
     }
@@ -286,10 +295,10 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
                 }
             }
         } catch (InstantiationException
-                | IllegalAccessException
-                | InvocationTargetException
-                | NoSuchMethodException
-                | ClassNotFoundException e) {
+                 | IllegalAccessException
+                 | InvocationTargetException
+                 | NoSuchMethodException
+                 | ClassNotFoundException e) {
             throw new DatabaseException(e);
         }
     }
@@ -375,8 +384,4 @@ public abstract class HibernateDatabase extends 
AbstractJdbcDatabase {
     public boolean isCaseSensitive() {
         return false;
     }
-
-
-
-
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringBeanDatabase.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringBeanDatabase.java
index 7c08d734ec..1edc2ac9c1 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringBeanDatabase.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringBeanDatabase.java
@@ -85,27 +85,30 @@ public class HibernateSpringBeanDatabase extends 
HibernateDatabase {
         BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
         XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
         reader.setNamespaceAware(true);
-        HibernateConnection connection = getHibernateConnection();
-        String path = Optional.ofNullable(connection.getPath())
-                .orElseThrow(() -> new IllegalStateException("Hibernate 
connection path is null"));
-        reader.loadBeanDefinitions(new ClassPathResource(path));
 
-        Properties props = Optional.ofNullable(connection.getProperties())
-                .orElseThrow(() -> new IllegalStateException("Hibernate 
connection properties are null"));
-
-        String beanName = Optional.ofNullable(props.getProperty("bean"))
-                .orElseThrow(() -> new IllegalStateException("A 'bean' name is 
required, definition in '" + path + "'."));
-
-        try {
-            beanDefinition = registry.getBeanDefinition(beanName);
-            
Optional.ofNullable(beanDefinition.getPropertyValues().getPropertyValue("hibernateProperties"))
-                    .map(PropertyValue::getValue)
-                    .filter(ManagedProperties.class::isInstance)
-                    .map(ManagedProperties.class::cast)
-                    .ifPresent(p -> beanDefinitionProperties = p);
-        } catch (NoSuchBeanDefinitionException e) {
-            throw new IllegalStateException(
-                    "A bean named '" + beanName + "' could not be found in '" 
+ path + "'.", e);
+        // Fix: Use try-with-resources to ensure HibernateConnection is closed 
(PMD #8)
+        try (HibernateConnection connection = getHibernateConnection()) {
+            String path = Optional.ofNullable(connection.getPath())
+                    .orElseThrow(() -> new IllegalStateException("Hibernate 
connection path is null"));
+            reader.loadBeanDefinitions(new ClassPathResource(path));
+
+            Properties props = Optional.ofNullable(connection.getProperties())
+                    .orElseThrow(() -> new IllegalStateException("Hibernate 
connection properties are null"));
+
+            String beanName = Optional.ofNullable(props.getProperty("bean"))
+                    .orElseThrow(() -> new IllegalStateException("A 'bean' 
name is required, definition in '" + path + "'."));
+
+            try {
+                beanDefinition = registry.getBeanDefinition(beanName);
+                
Optional.ofNullable(beanDefinition.getPropertyValues().getPropertyValue("hibernateProperties"))
+                        .map(PropertyValue::getValue)
+                        .filter(ManagedProperties.class::isInstance)
+                        .map(ManagedProperties.class::cast)
+                        .ifPresent(p -> beanDefinitionProperties = p);
+            } catch (NoSuchBeanDefinitionException e) {
+                throw new IllegalStateException(
+                        "A bean named '" + beanName + "' could not be found in 
'" + path + "'.", e);
+            }
         }
     }
 
@@ -122,26 +125,23 @@ public class HibernateSpringBeanDatabase extends 
HibernateDatabase {
                     sources.addAnnotatedClass(findClass(className));
                 });
 
-        try {
-            // Add mapping locations
-            ResourcePatternResolver resourcePatternResolver = new 
PathMatchingResourcePatternResolver();
-            extractListProperty(properties, "mappingLocations")
-                    .forEach(mappingLocation -> {
-                        try {
-                            
Scope.getCurrentScope().getLog(getClass()).info("Found mappingLocation " + 
mappingLocation);
-                            Resource[] resources = 
resourcePatternResolver.getResources(mappingLocation);
-                            for (Resource resource : resources) {
-                                URL url = resource.getURL();
-                                
Scope.getCurrentScope().getLog(getClass()).info("Adding resource  " + url);
-                                sources.addURL(url);
-                            }
-                        } catch (IOException e) {
-                            throw new RuntimeException(e);
+        // Add mapping locations
+        ResourcePatternResolver resourcePatternResolver = new 
PathMatchingResourcePatternResolver();
+        extractListProperty(properties, "mappingLocations")
+                .forEach(mappingLocation -> {
+                    try {
+                        Scope.getCurrentScope().getLog(getClass()).info("Found 
mappingLocation " + mappingLocation);
+                        Resource[] resources = 
resourcePatternResolver.getResources(mappingLocation);
+                        for (Resource resource : resources) {
+                            URL url = resource.getURL();
+                            
Scope.getCurrentScope().getLog(getClass()).info("Adding resource  " + url);
+                            sources.addURL(url);
                         }
-                    });
-        } catch (Exception e) {
-            throw new DatabaseException(e);
-        }
+                    } catch (IOException e) {
+                        // Fix: Pass 'e' as cause to preserve stack trace (PMD 
#9)
+                        throw new RuntimeException("Error resolving mapping 
location: " + mappingLocation, e);
+                    }
+                });
     }
 
     private Stream<String> extractListProperty(MutablePropertyValues 
properties, String propertyName) {
@@ -168,7 +168,7 @@ public class HibernateSpringBeanDatabase extends 
HibernateDatabase {
             }
         } catch (ClassNotFoundException e) {
             throw new IllegalStateException(
-                    "Unable to find required class: '" + className + "'. 
Please check classpath and class name.");
+                    "Unable to find required class: '" + className + "'. 
Please check classpath and class name.", e);
         }
     }
 
@@ -181,4 +181,4 @@ public class HibernateSpringBeanDatabase extends 
HibernateDatabase {
     protected String getDefaultDatabaseProductName() {
         return "Hibernate Spring Bean";
     }
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringPackageDatabase.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringPackageDatabase.java
index 3c84171faa..33c9ce63bb 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringPackageDatabase.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/HibernateSpringPackageDatabase.java
@@ -5,6 +5,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 import jakarta.persistence.spi.PersistenceUnitInfo;
 
@@ -32,42 +33,38 @@ public class HibernateSpringPackageDatabase extends 
JpaPersistenceDatabase {
 
     @Override
     public boolean isCorrectDatabaseImplementation(DatabaseConnection conn) {
-        return conn.getURL().startsWith("hibernate:spring:") && 
!isXmlFile(conn);
+        return Optional.ofNullable(conn.getURL())
+                .map(url -> url.startsWith("hibernate:spring:") && 
!isXmlFile(conn))
+                .orElse(false);
     }
 
     @Override
     public int getPriority() {
-        return super.getPriority()
-                + 10; // want this to be picked over 
HibernateSpringBeanDatabase if it is not xml file
+        return super.getPriority() + 10; // want this to be picked over 
HibernateSpringBeanDatabase if it is not xml file
     }
 
     /**
      * Return true if the given path is a spring XML file.
      */
+    @SuppressWarnings("PMD.CloseResource")
     protected boolean isXmlFile(DatabaseConnection connection) {
-        HibernateConnection hibernateConnection;
-        if (connection instanceof liquibase.database.jvm.JdbcConnection) {
-            Object underlyingConnection =
-                    connection.getUnderlyingConnection();
-            if (underlyingConnection instanceof HibernateConnection) {
-                hibernateConnection = (HibernateConnection) 
underlyingConnection;
-            } else {
-                return false;
-            }
-        } else if (connection instanceof HibernateConnection) {
-            hibernateConnection = (HibernateConnection) connection;
-        } else {
+        HibernateConnection hibernateConnection = 
getHibernateConnection(connection);
+
+        if (hibernateConnection == null || hibernateConnection.getPath() == 
null) {
             return false;
         }
 
         String path = hibernateConnection.getPath();
-        if (path == null) {
-            return false;
-        }
+
+        // If it looks like a path, treat as XML
         if (path.contains("/")) {
             return true;
         }
-        ClassPathResource resource = new ClassPathResource(path);
+
+        // Use Context ClassLoader for resource lookup (PMD #11 compliance)
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        ClassPathResource resource = new ClassPathResource(path, loader);
+
         try {
             return resource.exists() && !resource.getFile().isDirectory();
         } catch (IOException e) {
@@ -75,70 +72,65 @@ public class HibernateSpringPackageDatabase extends 
JpaPersistenceDatabase {
         }
     }
 
+    private HibernateConnection getHibernateConnection(DatabaseConnection 
conn) {
+        if (conn instanceof HibernateConnection hc) {
+            return hc;
+        }
+        if (conn instanceof liquibase.database.jvm.JdbcConnection jdbc &&
+                jdbc.getUnderlyingConnection() instanceof HibernateConnection 
hc) {
+            return hc;
+        }
+        return null;
+    }
+
     @Override
     protected EntityManagerFactoryBuilderImpl 
createEntityManagerFactoryBuilder() {
         DefaultPersistenceUnitManager internalPersistenceUnitManager = new 
DefaultPersistenceUnitManager();
-        internalPersistenceUnitManager.setResourceLoader(
-                new 
DefaultResourceLoader(Scope.getCurrentScope().getClassLoader()));
 
-        String path = getHibernateConnection().getPath();
-        if (path == null) {
-            throw new IllegalStateException("Hibernate connection path is 
null");
-        }
-        String[] packagesToScan = path.split(",");
+        // Fix: Use Thread Context ClassLoader for J2EE/Spring compliance (PMD 
#11)
+        ClassLoader contextClassLoader = 
Thread.currentThread().getContextClassLoader();
+        internalPersistenceUnitManager.setResourceLoader(new 
DefaultResourceLoader(contextClassLoader));
 
-        for (String packageName : packagesToScan) {
-            Scope.getCurrentScope().getLog(getClass()).info("Found package " + 
packageName);
-        }
+        // Fix: Use try-with-resources to ensure connection is handled 
correctly (PMD #10)
+        try (HibernateConnection connection = getHibernateConnection()) {
+            String path = connection.getPath();
+            if (path == null) {
+                throw new IllegalStateException("Hibernate connection path is 
null");
+            }
+            String[] packagesToScan = path.split(",");
 
-        internalPersistenceUnitManager.setPackagesToScan(packagesToScan);
+            for (String packageName : packagesToScan) {
+                Scope.getCurrentScope().getLog(getClass()).info("Found package 
" + packageName);
+            }
 
-        internalPersistenceUnitManager.preparePersistenceUnitInfos();
-        PersistenceUnitInfo persistenceUnitInfo = 
internalPersistenceUnitManager.obtainDefaultPersistenceUnitInfo();
-        HibernateJpaVendorAdapter jpaVendorAdapter = new 
HibernateJpaVendorAdapter();
+            internalPersistenceUnitManager.setPackagesToScan(packagesToScan);
+            internalPersistenceUnitManager.preparePersistenceUnitInfos();
+            PersistenceUnitInfo persistenceUnitInfo = 
internalPersistenceUnitManager.obtainDefaultPersistenceUnitInfo();
+            HibernateJpaVendorAdapter jpaVendorAdapter = new 
HibernateJpaVendorAdapter();
 
-        if (persistenceUnitInfo instanceof SmartPersistenceUnitInfo) {
-            ((SmartPersistenceUnitInfo) persistenceUnitInfo)
-                    
.setPersistenceProviderPackageName(jpaVendorAdapter.getPersistenceProviderRootPackage());
-        }
+            if (persistenceUnitInfo instanceof SmartPersistenceUnitInfo) {
+                ((SmartPersistenceUnitInfo) persistenceUnitInfo)
+                        
.setPersistenceProviderPackageName(jpaVendorAdapter.getPersistenceProviderRootPackage());
+            }
 
-        Map<String, String> map = new HashMap<>();
-        map.put(AvailableSettings.DIALECT, 
getProperty(AvailableSettings.DIALECT));
-        map.put(HibernateDatabase.HIBERNATE_TEMP_USE_JDBC_METADATA_DEFAULTS, 
Boolean.FALSE.toString());
-        map.put(AvailableSettings.USE_SECOND_LEVEL_CACHE, 
Boolean.FALSE.toString());
-        map.put(
-                AvailableSettings.PHYSICAL_NAMING_STRATEGY,
-                
getHibernateConnection().getProperties().getProperty(AvailableSettings.PHYSICAL_NAMING_STRATEGY));
-        map.put(
-                AvailableSettings.IMPLICIT_NAMING_STRATEGY,
-                
getHibernateConnection().getProperties().getProperty(AvailableSettings.IMPLICIT_NAMING_STRATEGY));
-        map.put(
-                AvailableSettings.SCANNER_DISCOVERY,
-                ""); // disable scanning of all classes and hbm.xml files. 
Only scan speficied packages
-        map.put(
-                EnversSettings.AUDIT_TABLE_PREFIX,
-                
getHibernateConnection().getProperties().getProperty(EnversSettings.AUDIT_TABLE_PREFIX,
 ""));
-        map.put(
-                EnversSettings.AUDIT_TABLE_SUFFIX,
-                
getHibernateConnection().getProperties().getProperty(EnversSettings.AUDIT_TABLE_SUFFIX,
 "_AUD"));
-        map.put(
-                EnversSettings.REVISION_FIELD_NAME,
-                
getHibernateConnection().getProperties().getProperty(EnversSettings.REVISION_FIELD_NAME,
 "REV"));
-        map.put(
-                EnversSettings.REVISION_TYPE_FIELD_NAME,
-                getHibernateConnection()
-                        .getProperties()
-                        .getProperty(EnversSettings.REVISION_TYPE_FIELD_NAME, 
"REVTYPE"));
-        map.put(
-                AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA,
-                
getProperty(AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA));
-        map.put(AvailableSettings.TIMEZONE_DEFAULT_STORAGE, 
getProperty(AvailableSettings.TIMEZONE_DEFAULT_STORAGE));
-        PersistenceUnitInfoDescriptor persistenceUnitInfoDescriptor =
-                createPersistenceUnitInfoDescriptor(persistenceUnitInfo);
-        EntityManagerFactoryBuilderImpl builder = 
(EntityManagerFactoryBuilderImpl)
-                
Bootstrap.getEntityManagerFactoryBuilder(persistenceUnitInfoDescriptor, map);
-
-        return builder;
+            Map<String, String> map = new HashMap<>();
+            map.put(AvailableSettings.DIALECT, 
getProperty(AvailableSettings.DIALECT));
+            
map.put(HibernateDatabase.HIBERNATE_TEMP_USE_JDBC_METADATA_DEFAULTS, 
Boolean.FALSE.toString());
+            map.put(AvailableSettings.USE_SECOND_LEVEL_CACHE, 
Boolean.FALSE.toString());
+            map.put(AvailableSettings.PHYSICAL_NAMING_STRATEGY, 
connection.getProperties().getProperty(AvailableSettings.PHYSICAL_NAMING_STRATEGY));
+            map.put(AvailableSettings.IMPLICIT_NAMING_STRATEGY, 
connection.getProperties().getProperty(AvailableSettings.IMPLICIT_NAMING_STRATEGY));
+            map.put(AvailableSettings.SCANNER_DISCOVERY, "");
+            map.put(EnversSettings.AUDIT_TABLE_PREFIX, 
connection.getProperties().getProperty(EnversSettings.AUDIT_TABLE_PREFIX, ""));
+            map.put(EnversSettings.AUDIT_TABLE_SUFFIX, 
connection.getProperties().getProperty(EnversSettings.AUDIT_TABLE_SUFFIX, 
"_AUD"));
+            map.put(EnversSettings.REVISION_FIELD_NAME, 
connection.getProperties().getProperty(EnversSettings.REVISION_FIELD_NAME, 
"REV"));
+            map.put(EnversSettings.REVISION_TYPE_FIELD_NAME, 
connection.getProperties().getProperty(EnversSettings.REVISION_TYPE_FIELD_NAME, 
"REVTYPE"));
+            map.put(AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA, 
getProperty(AvailableSettings.USE_NATIONALIZED_CHARACTER_DATA));
+            map.put(AvailableSettings.TIMEZONE_DEFAULT_STORAGE, 
getProperty(AvailableSettings.TIMEZONE_DEFAULT_STORAGE));
+
+            PersistenceUnitInfoDescriptor persistenceUnitInfoDescriptor = 
createPersistenceUnitInfoDescriptor(persistenceUnitInfo);
+            return (EntityManagerFactoryBuilderImpl) 
Bootstrap.getEntityManagerFactoryBuilder(persistenceUnitInfoDescriptor, map);
+
+        }
     }
 
     public PersistenceUnitInfoDescriptor 
createPersistenceUnitInfoDescriptor(PersistenceUnitInfo info) {
@@ -170,4 +162,4 @@ public class HibernateSpringPackageDatabase extends 
JpaPersistenceDatabase {
     protected String getDefaultDatabaseProductName() {
         return "Hibernate Spring Package";
     }
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpConnectionProvider.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpConnectionProvider.java
index 1808a47f77..3e7884f52e 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpConnectionProvider.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpConnectionProvider.java
@@ -1,5 +1,6 @@
 package liquibase.ext.hibernate.database;
 
+import java.io.Serial;
 import java.sql.Connection;
 import java.sql.SQLException;
 
@@ -10,13 +11,19 @@ import 
org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
  */
 class NoOpConnectionProvider implements ConnectionProvider {
 
+    // Fix: Classes implementing Serializable should set a serialVersionUID 
(PMD #12)
+    @Serial
+    private static final long serialVersionUID = 1L;
+
     @Override
     public Connection getConnection() throws SQLException {
         throw new SQLException("No connection");
     }
 
     @Override
-    public void closeConnection(Connection conn) {}
+    public void closeConnection(Connection conn) {
+        // No-op
+    }
 
     @Override
     public boolean supportsAggressiveRelease() {
@@ -24,7 +31,7 @@ class NoOpConnectionProvider implements ConnectionProvider {
     }
 
     @Override
-    public boolean isUnwrappableAs(Class unwrapType) {
+    public boolean isUnwrappableAs(Class<?> unwrapType) {
         return false;
     }
 
@@ -33,15 +40,31 @@ class NoOpConnectionProvider implements ConnectionProvider {
         return null;
     }
 
+    /**
+     * Helper for multi-tenant or legacy calls.
+     */
     public Connection getConnection(String tenantIdentifier) throws 
SQLException {
         return getConnection();
     }
 
+    /**
+     * Helper for Hibernate 5/6 SPI calls.
+     */
     public Connection getConnection(Object o) throws SQLException {
         return getConnection();
     }
 
-    public void releaseConnection(Object tenantIdentifier, Connection 
connection) {}
+    /**
+     * No-op release.
+     */
+    public void releaseConnection(Object tenantIdentifier, Connection 
connection) {
+        // No-op
+    }
 
-    public void releaseConnection(String tenantIdentifier, Connection 
connection) {}
-}
+    /**
+     * No-op release.
+     */
+    public void releaseConnection(String tenantIdentifier, Connection 
connection) {
+        // No-op
+    }
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpMultiTenantConnectionProvider.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpMultiTenantConnectionProvider.java
index 1ea179ef75..24c231ce2f 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpMultiTenantConnectionProvider.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/NoOpMultiTenantConnectionProvider.java
@@ -1,5 +1,6 @@
 package liquibase.ext.hibernate.database;
 
+import java.io.Serial;
 import java.sql.Connection;
 import java.sql.SQLException;
 
@@ -10,8 +11,12 @@ import 
org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
  */
 class NoOpMultiTenantConnectionProvider implements 
MultiTenantConnectionProvider {
 
+    // Fix: Classes implementing Serializable should set a serialVersionUID 
(PMD #13)
+    @Serial
+    private static final long serialVersionUID = 1L;
+
     @Override
-    public boolean isUnwrappableAs(Class unwrapType) {
+    public boolean isUnwrappableAs(Class<?> unwrapType) {
         return false;
     }
 
@@ -26,22 +31,32 @@ class NoOpMultiTenantConnectionProvider implements 
MultiTenantConnectionProvider
     }
 
     @Override
-    public void releaseAnyConnection(Connection connection) {}
+    public void releaseAnyConnection(Connection connection) {
+        // No-op
+    }
 
-    public Connection getConnection(String s) {
+    public Connection getConnection(String tenantIdentifier) throws 
SQLException {
         return null;
     }
 
-    public void releaseConnection(String s, Connection connection) {}
+    public void releaseConnection(String tenantIdentifier, Connection 
connection) {
+        // No-op
+    }
 
-    public Connection getConnection(Object tenantIdentifier) {
+    @Override
+    public Connection getConnection(Object tenantIdentifier) throws 
SQLException {
+        // Fix: Added missing @Override annotation (PMD #14)
         return null;
     }
 
-    public void releaseConnection(Object tenantIdentifier, Connection 
connection) {}
+    @Override
+    public void releaseConnection(Object tenantIdentifier, Connection 
connection) {
+        // Fix: Added missing @Override annotation (PMD #15)
+        // No-op
+    }
 
     @Override
     public boolean supportsAggressiveRelease() {
         return false;
     }
-}
+}
\ No newline at end of file
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnection.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnection.java
index ffcf9a8554..8c1795a532 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnection.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnection.java
@@ -5,6 +5,7 @@ import java.io.StringReader;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
 import java.sql.*;
+import java.util.Collections;
 import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.Executor;
@@ -52,12 +53,12 @@ public class HibernateConnection implements Connection {
     /**
      * Creates properties to attach to this connection based on the passed 
query string.
      */
-    protected Properties readProperties(String queryString) {
+    protected final Properties readProperties(String queryString) {
         Properties properties = new Properties();
-        queryString = queryString.replaceAll("&", System.lineSeparator());
+        String propertiesString = queryString.replaceAll("&", 
System.lineSeparator());
         try {
-            queryString = URLDecoder.decode(queryString, 
StandardCharsets.UTF_8);
-            properties.load(new StringReader(queryString));
+            propertiesString = URLDecoder.decode(propertiesString, 
StandardCharsets.UTF_8);
+            properties.load(new StringReader(propertiesString));
         } catch (IOException ioe) {
             throw new IllegalStateException("Failed to read properties from 
url", ioe);
         }
@@ -101,193 +102,242 @@ public class HibernateConnection implements Connection {
     /// JDBC METHODS
     
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+    @Override
     public Statement createStatement() {
         return null;
     }
 
+    @Override
     public PreparedStatement prepareStatement(String sql) {
         return null;
     }
 
+    @Override
     public CallableStatement prepareCall(String sql) {
         return null;
     }
 
+    @Override
     public String nativeSQL(String sql) {
         return null;
     }
 
+    @Override
     public void setAutoCommit(boolean autoCommit) {}
 
+    @Override
     public boolean getAutoCommit() {
         return false;
     }
 
+    @Override
     public void commit() {}
 
+    @Override
     public void rollback() {}
 
+    @Override
     public void close() {}
 
+    @Override
     public boolean isClosed() {
         return false;
     }
 
+    @Override
     public DatabaseMetaData getMetaData() {
         return new HibernateConnectionMetadata(url);
     }
 
+    @Override
     public void setReadOnly(boolean readOnly) {}
 
+    @Override
     public boolean isReadOnly() {
         return true;
     }
 
+    @Override
     public void setCatalog(String catalog) {}
 
+    @Override
     public String getCatalog() {
         return "HIBERNATE";
     }
 
+    @Override
     public void setTransactionIsolation(int level) {}
 
+    @Override
     public int getTransactionIsolation() {
         return Connection.TRANSACTION_NONE;
     }
 
+    @Override
     public SQLWarning getWarnings() {
         return null;
     }
 
+    @Override
     public void clearWarnings() {}
 
+    @Override
     public Statement createStatement(int resultSetType, int 
resultSetConcurrency) {
         return null;
     }
 
+    @Override
     public PreparedStatement prepareStatement(String sql, int resultSetType, 
int resultSetConcurrency) {
         return null;
     }
 
+    @Override
     public CallableStatement prepareCall(String sql, int resultSetType, int 
resultSetConcurrency) {
         return null;
     }
 
+    @Override
     public Map<String, Class<?>> getTypeMap() {
-        return null;
+        return Collections.emptyMap();
     }
 
+    @Override
     public void setTypeMap(Map<String, Class<?>> map) {}
 
+    @Override
     public void setHoldability(int holdability) {}
 
+    @Override
     public int getHoldability() {
         return 0;
     }
 
+    @Override
     public Savepoint setSavepoint() {
         return null;
     }
 
+    @Override
     public Savepoint setSavepoint(String name) {
         return null;
     }
 
+    @Override
     public void rollback(Savepoint savepoint) {}
 
+    @Override
     public void releaseSavepoint(Savepoint savepoint) {}
 
+    @Override
     public Statement createStatement(int resultSetType, int 
resultSetConcurrency, int resultSetHoldability) {
         return null;
     }
 
+    @Override
     public PreparedStatement prepareStatement(
             String sql, int resultSetType, int resultSetConcurrency, int 
resultSetHoldability) {
         return null;
     }
 
+    @Override
     public CallableStatement prepareCall(
             String sql, int resultSetType, int resultSetConcurrency, int 
resultSetHoldability) {
         return null;
     }
 
+    @Override
     public PreparedStatement prepareStatement(String sql, int 
autoGeneratedKeys) {
         return null;
     }
 
+    @Override
     public PreparedStatement prepareStatement(String sql, int[] columnIndexes) 
{
         return null;
     }
 
+    @Override
     public PreparedStatement prepareStatement(String sql, String[] 
columnNames) {
         return null;
     }
 
+    @Override
     public Clob createClob() {
         return null;
     }
 
+    @Override
     public Blob createBlob() {
         return null;
     }
 
+    @Override
     public NClob createNClob() {
         return null;
     }
 
+    @Override
     public SQLXML createSQLXML() {
         return null;
     }
 
+    @Override
     public boolean isValid(int timeout) {
         return false;
     }
 
+    @Override
     public void setClientInfo(String name, String value) {}
 
+    @Override
     public void setClientInfo(Properties properties) {}
 
+    @Override
     public String getClientInfo(String name) {
         return null;
     }
 
+    @Override
     public Properties getClientInfo() {
-        return null;
+        return new Properties();
     }
 
+    @Override
     public Array createArrayOf(String typeName, Object[] elements) {
         return null;
     }
 
+    @Override
     public Struct createStruct(String typeName, Object[] attributes) {
         return null;
     }
 
+    @Override
     public <T> T unwrap(Class<T> iface) {
         return null;
     }
 
+    @Override
     public boolean isWrapperFor(Class<?> iface) {
         return false;
     }
 
-    // @Override only in java 1.7
+    @Override
     public void abort(Executor arg0) {}
 
-    // @Override only in java 1.7
+    @Override
     public int getNetworkTimeout() {
         return 0;
     }
 
-    // @Override only in java 1.7
+    @Override
     public String getSchema() {
         return "HIBERNATE";
     }
 
-    // @Override only in java 1.7
+    @Override
     public void setNetworkTimeout(Executor arg0, int arg1) {}
 
-    // @Override only in java 1.7
+    @Override
     public void setSchema(String arg0) {}
 
     public ResourceAccessor getResourceAccessor() {
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnectionMetadata.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnectionMetadata.java
index 007be46d49..732ff32d97 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnectionMetadata.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateConnectionMetadata.java
@@ -16,535 +16,668 @@ public class HibernateConnectionMetadata implements 
DatabaseMetaData {
         this.url = url;
     }
 
+    @Override
     public boolean allProceduresAreCallable() {
         return false;
     }
 
+    @Override
     public boolean allTablesAreSelectable() {
         return false;
     }
 
+    @Override
     public String getURL() {
         return url;
     }
 
+    @Override
     public String getUserName() {
         return null;
     }
 
+    @Override
     public boolean isReadOnly() {
         return true;
     }
 
+    @Override
     public boolean nullsAreSortedHigh() {
         return false;
     }
 
+    @Override
     public boolean nullsAreSortedLow() {
         return false;
     }
 
+    @Override
     public boolean nullsAreSortedAtStart() {
         return false;
     }
 
+    @Override
     public boolean nullsAreSortedAtEnd() {
         return false;
     }
 
+    @Override
     public String getDatabaseProductName() {
         return "Hibernate";
     }
 
+    @Override
     public String getDatabaseProductVersion() {
         return Version.getVersionString();
     }
 
+    @Override
     public String getDriverName() {
         return null;
     }
 
+    @Override
     public String getDriverVersion() {
         return "0";
     }
 
+    @Override
     public int getDriverMajorVersion() {
         return 0;
     }
 
+    @Override
     public int getDriverMinorVersion() {
         return 0;
     }
 
+    @Override
     public boolean usesLocalFiles() {
         return false;
     }
 
+    @Override
     public boolean usesLocalFilePerTable() {
         return false;
     }
 
+    @Override
     public boolean supportsMixedCaseIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean storesUpperCaseIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean storesLowerCaseIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean storesMixedCaseIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean supportsMixedCaseQuotedIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean storesUpperCaseQuotedIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean storesLowerCaseQuotedIdentifiers() {
         return false;
     }
 
+    @Override
     public boolean storesMixedCaseQuotedIdentifiers() {
         return false;
     }
 
+    @Override
     public String getIdentifierQuoteString() {
         return null;
     }
 
+    @Override
     public String getSQLKeywords() {
         return ""; // do not return null here due to 
liquibase.database.jvm.JdbcConnection:30 to avoid NPE's there
     }
 
+    @Override
     public String getNumericFunctions() {
         return null;
     }
 
+    @Override
     public String getStringFunctions() {
         return null;
     }
 
+    @Override
     public String getSystemFunctions() {
         return null;
     }
 
+    @Override
     public String getTimeDateFunctions() {
         return null;
     }
 
+    @Override
     public String getSearchStringEscape() {
         return null;
     }
 
+    @Override
     public String getExtraNameCharacters() {
         return null;
     }
 
+    @Override
     public boolean supportsAlterTableWithAddColumn() {
         return false;
     }
 
+    @Override
     public boolean supportsAlterTableWithDropColumn() {
         return false;
     }
 
+    @Override
     public boolean supportsColumnAliasing() {
         return false;
     }
 
+    @Override
     public boolean nullPlusNonNullIsNull() {
         return false;
     }
 
+    @Override
     public boolean supportsConvert() {
         return false;
     }
 
+    @Override
     public boolean supportsConvert(int fromType, int toType) {
         return false;
     }
 
+    @Override
     public boolean supportsTableCorrelationNames() {
         return false;
     }
 
+    @Override
     public boolean supportsDifferentTableCorrelationNames() {
         return false;
     }
 
+    @Override
     public boolean supportsExpressionsInOrderBy() {
         return false;
     }
 
+    @Override
     public boolean supportsOrderByUnrelated() {
         return false;
     }
 
+    @Override
     public boolean supportsGroupBy() {
         return false;
     }
 
+    @Override
     public boolean supportsGroupByUnrelated() {
         return false;
     }
 
+    @Override
     public boolean supportsGroupByBeyondSelect() {
         return false;
     }
 
+    @Override
     public boolean supportsLikeEscapeClause() {
         return false;
     }
 
+    @Override
     public boolean supportsMultipleResultSets() {
         return false;
     }
 
+    @Override
     public boolean supportsMultipleTransactions() {
         return false;
     }
 
+    @Override
     public boolean supportsNonNullableColumns() {
         return false;
     }
 
+    @Override
     public boolean supportsMinimumSQLGrammar() {
         return false;
     }
 
+    @Override
     public boolean supportsCoreSQLGrammar() {
         return false;
     }
 
+    @Override
     public boolean supportsExtendedSQLGrammar() {
         return false;
     }
 
+    @Override
     public boolean supportsANSI92EntryLevelSQL() {
         return false;
     }
 
+    @Override
     public boolean supportsANSI92IntermediateSQL() {
         return false;
     }
 
+    @Override
     public boolean supportsANSI92FullSQL() {
         return false;
     }
 
+    @Override
     public boolean supportsIntegrityEnhancementFacility() {
         return false;
     }
 
+    @Override
     public boolean supportsOuterJoins() {
         return false;
     }
 
+    @Override
     public boolean supportsFullOuterJoins() {
         return false;
     }
 
+    @Override
     public boolean supportsLimitedOuterJoins() {
         return false;
     }
 
+    @Override
     public String getSchemaTerm() {
         return null;
     }
 
+    @Override
     public String getProcedureTerm() {
         return null;
     }
 
+    @Override
     public String getCatalogTerm() {
         return null;
     }
 
+    @Override
     public boolean isCatalogAtStart() {
         return false;
     }
 
+    @Override
     public String getCatalogSeparator() {
         return null;
     }
 
+    @Override
     public boolean supportsSchemasInDataManipulation() {
         return false;
     }
 
+    @Override
     public boolean supportsSchemasInProcedureCalls() {
         return false;
     }
 
+    @Override
     public boolean supportsSchemasInTableDefinitions() {
         return false;
     }
 
+    @Override
     public boolean supportsSchemasInIndexDefinitions() {
         return false;
     }
 
+    @Override
     public boolean supportsSchemasInPrivilegeDefinitions() {
         return false;
     }
 
+    @Override
     public boolean supportsCatalogsInDataManipulation() {
         return false;
     }
 
+    @Override
     public boolean supportsCatalogsInProcedureCalls() {
         return false;
     }
 
+    @Override
     public boolean supportsCatalogsInTableDefinitions() {
         return false;
     }
 
+    @Override
     public boolean supportsCatalogsInIndexDefinitions() {
         return false;
     }
 
+    @Override
     public boolean supportsCatalogsInPrivilegeDefinitions() {
         return false;
     }
 
+    @Override
     public boolean supportsPositionedDelete() {
         return false;
     }
 
+    @Override
     public boolean supportsPositionedUpdate() {
         return false;
     }
 
+    @Override
     public boolean supportsSelectForUpdate() {
         return false;
     }
 
+    @Override
     public boolean supportsStoredProcedures() {
         return false;
     }
 
+    @Override
     public boolean supportsSubqueriesInComparisons() {
         return false;
     }
 
+    @Override
     public boolean supportsSubqueriesInExists() {
         return false;
     }
 
+    @Override
     public boolean supportsSubqueriesInIns() {
         return false;
     }
 
+    @Override
     public boolean supportsSubqueriesInQuantifieds() {
         return false;
     }
 
+    @Override
     public boolean supportsCorrelatedSubqueries() {
         return false;
     }
 
+    @Override
     public boolean supportsUnion() {
         return false;
     }
 
+    @Override
     public boolean supportsUnionAll() {
         return false;
     }
 
+    @Override
     public boolean supportsOpenCursorsAcrossCommit() {
         return false;
     }
 
+    @Override
     public boolean supportsOpenCursorsAcrossRollback() {
         return false;
     }
 
+    @Override
     public boolean supportsOpenStatementsAcrossCommit() {
         return false;
     }
 
+    @Override
     public boolean supportsOpenStatementsAcrossRollback() {
         return false;
     }
 
+    @Override
     public int getMaxBinaryLiteralLength() {
         return 0;
     }
 
+    @Override
     public int getMaxCharLiteralLength() {
         return 0;
     }
 
+    @Override
     public int getMaxColumnNameLength() {
         return 0;
     }
 
+    @Override
     public int getMaxColumnsInGroupBy() {
         return 0;
     }
 
+    @Override
     public int getMaxColumnsInIndex() {
         return 0;
     }
 
+    @Override
     public int getMaxColumnsInOrderBy() {
         return 0;
     }
 
+    @Override
     public int getMaxColumnsInSelect() {
         return 0;
     }
 
+    @Override
     public int getMaxColumnsInTable() {
         return 0;
     }
 
+    @Override
     public int getMaxConnections() {
         return 0;
     }
 
+    @Override
     public int getMaxCursorNameLength() {
         return 0;
     }
 
+    @Override
     public int getMaxIndexLength() {
         return 0;
     }
 
+    @Override
     public int getMaxSchemaNameLength() {
         return 0;
     }
 
+    @Override
     public int getMaxProcedureNameLength() {
         return 0;
     }
 
+    @Override
     public int getMaxCatalogNameLength() {
         return 0;
     }
 
+    @Override
     public int getMaxRowSize() {
         return 0;
     }
 
+    @Override
     public boolean doesMaxRowSizeIncludeBlobs() {
         return false;
     }
 
+    @Override
     public int getMaxStatementLength() {
         return 0;
     }
 
+    @Override
     public int getMaxStatements() {
         return 0;
     }
 
+    @Override
     public int getMaxTableNameLength() {
         return 0;
     }
 
+    @Override
     public int getMaxTablesInSelect() {
         return 0;
     }
 
+    @Override
     public int getMaxUserNameLength() {
         return 0;
     }
 
+    @Override
     public int getDefaultTransactionIsolation() {
         return 0;
     }
 
+    @Override
     public boolean supportsTransactions() {
         return false;
     }
 
+    @Override
     public boolean supportsTransactionIsolationLevel(int level) {
         return false;
     }
 
+    @Override
     public boolean supportsDataDefinitionAndDataManipulationTransactions() {
         return false;
     }
 
+    @Override
     public boolean supportsDataManipulationTransactionsOnly() {
         return false;
     }
 
+    @Override
     public boolean dataDefinitionCausesTransactionCommit() {
         return false;
     }
 
+    @Override
     public boolean dataDefinitionIgnoredInTransactions() {
         return false;
     }
 
+    @Override
     public ResultSet getProcedures(String catalog, String schemaPattern, 
String procedureNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getProcedureColumns(
             String catalog, String schemaPattern, String procedureNamePattern, 
String columnNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getTables(String catalog, String schemaPattern, String 
tableNamePattern, String[] types) {
         return null;
     }
 
+    @Override
     public ResultSet getSchemas() {
         return null;
     }
 
+    @Override
     public ResultSet getCatalogs() {
         return null;
     }
 
+    @Override
     public ResultSet getTableTypes() {
         return null;
     }
 
+    @Override
     public ResultSet getColumns(String catalog, String schemaPattern, String 
tableNamePattern, String columnNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getColumnPrivileges(String catalog, String schema, String 
table, String columnNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getTablePrivileges(String catalog, String schemaPattern, 
String tableNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getBestRowIdentifier(String catalog, String schema, 
String table, int scope, boolean nullable) {
         return null;
     }
 
+    @Override
     public ResultSet getVersionColumns(String catalog, String schema, String 
table) {
         return null;
     }
 
+    @Override
     public ResultSet getPrimaryKeys(String catalog, String schema, String 
table) {
         return null;
     }
 
+    @Override
     public ResultSet getImportedKeys(String catalog, String schema, String 
table) {
         return null;
     }
 
+    @Override
     public ResultSet getExportedKeys(String catalog, String schema, String 
table) {
         return null;
     }
 
+    @Override
     public ResultSet getCrossReference(
             String parentCatalog,
             String parentSchema,
@@ -555,178 +688,219 @@ public class HibernateConnectionMetadata implements 
DatabaseMetaData {
         return null;
     }
 
+    @Override
     public ResultSet getTypeInfo() {
         return null;
     }
 
+    @Override
     public ResultSet getIndexInfo(String catalog, String schema, String table, 
boolean unique, boolean approximate) {
         return null;
     }
 
+    @Override
     public boolean supportsResultSetType(int type) {
         return false;
     }
 
+    @Override
     public boolean supportsResultSetConcurrency(int type, int concurrency) {
         return false;
     }
 
+    @Override
     public boolean ownUpdatesAreVisible(int type) {
         return false;
     }
 
+    @Override
     public boolean ownDeletesAreVisible(int type) {
         return false;
     }
 
+    @Override
     public boolean ownInsertsAreVisible(int type) {
         return false;
     }
 
+    @Override
     public boolean othersUpdatesAreVisible(int type) {
         return false;
     }
 
+    @Override
     public boolean othersDeletesAreVisible(int type) {
         return false;
     }
 
+    @Override
     public boolean othersInsertsAreVisible(int type) {
         return false;
     }
 
+    @Override
     public boolean updatesAreDetected(int type) {
         return false;
     }
 
+    @Override
     public boolean deletesAreDetected(int type) {
         return false;
     }
 
+    @Override
     public boolean insertsAreDetected(int type) {
         return false;
     }
 
+    @Override
     public boolean supportsBatchUpdates() {
         return false;
     }
 
+    @Override
     public ResultSet getUDTs(String catalog, String schemaPattern, String 
typeNamePattern, int[] types) {
         return null;
     }
 
+    @Override
     public Connection getConnection() {
         return null;
     }
 
+    @Override
     public boolean supportsSavepoints() {
         return false;
     }
 
+    @Override
     public boolean supportsNamedParameters() {
         return false;
     }
 
+    @Override
     public boolean supportsMultipleOpenResults() {
         return false;
     }
 
+    @Override
     public boolean supportsGetGeneratedKeys() {
         return false;
     }
 
+    @Override
     public ResultSet getSuperTypes(String catalog, String schemaPattern, 
String typeNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getSuperTables(String catalog, String schemaPattern, 
String tableNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getAttributes(
             String catalog, String schemaPattern, String typeNamePattern, 
String attributeNamePattern) {
         return null;
     }
 
+    @Override
     public boolean supportsResultSetHoldability(int holdability) {
         return false;
     }
 
+    @Override
     public int getResultSetHoldability() {
         return 0;
     }
 
+    @Override
     public int getDatabaseMajorVersion() {
         return 0;
     }
 
+    @Override
     public int getDatabaseMinorVersion() {
         return 0;
     }
 
+    @Override
     public int getJDBCMajorVersion() {
         return 0;
     }
 
+    @Override
     public int getJDBCMinorVersion() {
         return 0;
     }
 
+    @Override
     public int getSQLStateType() {
         return DatabaseMetaData.sqlStateSQL;
     }
 
+    @Override
     public boolean locatorsUpdateCopy() {
         return false;
     }
 
+    @Override
     public boolean supportsStatementPooling() {
         return false;
     }
 
+    @Override
     public RowIdLifetime getRowIdLifetime() {
         return null;
     }
 
+    @Override
     public ResultSet getSchemas(String catalog, String schemaPattern) {
         return null;
     }
 
+    @Override
     public boolean supportsStoredFunctionsUsingCallSyntax() {
         return false;
     }
 
+    @Override
     public boolean autoCommitFailureClosesAllResultSets() {
         return false;
     }
 
+    @Override
     public ResultSet getClientInfoProperties() {
         return null;
     }
 
+    @Override
     public ResultSet getFunctions(String catalog, String schemaPattern, String 
functionNamePattern) {
         return null;
     }
 
+    @Override
     public ResultSet getFunctionColumns(
             String catalog, String schemaPattern, String functionNamePattern, 
String columnNamePattern) {
         return null;
     }
 
+    @Override
     public <T> T unwrap(Class<T> iface) {
         return null;
     }
 
+    @Override
     public boolean isWrapperFor(Class<?> iface) {
         return false;
     }
 
-    // @Override only override for java 1.7
+    @Override
     public boolean generatedKeyAlwaysReturned() {
         return false;
     }
 
-    // @Override only override for java 1.7
+    @Override
     public ResultSet getPseudoColumns(String arg0, String arg1, String arg2, 
String arg3) {
         return null;
     }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateDriver.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateDriver.java
index 101573945b..9aced34aca 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateDriver.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/database/connection/HibernateDriver.java
@@ -15,31 +15,37 @@ public class HibernateDriver implements Driver, 
LiquibaseExtDriver {
 
     private ResourceAccessor resourceAccessor;
 
+    @Override
     public Connection connect(String url, Properties info)  {
         return new HibernateConnection(url, resourceAccessor);
     }
 
+    @Override
     public boolean acceptsURL(String url)  {
         return url.startsWith("hibernate:");
     }
 
+    @Override
     public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)  {
         return new DriverPropertyInfo[0];
     }
 
+    @Override
     public int getMajorVersion() {
         return 0;
     }
 
+    @Override
     public int getMinorVersion() {
         return 0;
     }
 
+    @Override
     public boolean jdbcCompliant() {
         return false;
     }
 
-    // @Override only override for java 1.7
+    @Override
     public Logger getParentLogger() throws SQLFeatureNotSupportedException {
         throw new SQLFeatureNotSupportedException();
     }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedForeignKeyChangeGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedForeignKeyChangeGenerator.java
index a4060189a0..31be8d5f07 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedForeignKeyChangeGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedForeignKeyChangeGenerator.java
@@ -37,7 +37,7 @@ public class ChangedForeignKeyChangeGenerator
             differences.removeDifference("updateRule");
             differences.removeDifference("validate");
             if (!differences.hasDifferences()) {
-                return null;
+                return new Change[0];
             }
         }
 
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedPrimaryKeyChangeGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedPrimaryKeyChangeGenerator.java
index 55a48c4a72..6a0c8649d8 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedPrimaryKeyChangeGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedPrimaryKeyChangeGenerator.java
@@ -36,7 +36,7 @@ public class ChangedPrimaryKeyChangeGenerator
             differences.removeDifference("unique");
             differences.removeDifference("validate");
             if (!differences.hasDifferences()) {
-                return null;
+                return new Change[0];
             }
         }
 
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedSequenceChangeGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedSequenceChangeGenerator.java
index a409d27015..1baffcea9d 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedSequenceChangeGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedSequenceChangeGenerator.java
@@ -21,8 +21,6 @@ package liquibase.ext.hibernate.diff;
 import java.util.Objects;
 import java.util.Set;
 
-import org.hibernate.id.enhanced.SequenceStyleGenerator;
-
 import liquibase.change.Change;
 import liquibase.database.Database;
 import liquibase.diff.Difference;
@@ -40,7 +38,11 @@ import liquibase.structure.core.Sequence;
 public class ChangedSequenceChangeGenerator
         extends 
liquibase.diff.output.changelog.core.ChangedSequenceChangeGenerator {
 
-    private static final Set<String> HIBERNATE_SEQUENCE_FIELDS = 
Set.of("name", "startValue", "incrementBy");
+    private static final String FIELD_NAME = "name";
+    private static final String FIELD_START_VALUE = "startValue";
+    private static final String FIELD_INCREMENT_BY = "incrementBy";
+
+    private static final Set<String> HIBERNATE_SEQUENCE_FIELDS = 
Set.of(FIELD_NAME, FIELD_START_VALUE, FIELD_INCREMENT_BY);
     
     // Default values used by Hibernate's SequenceStyleGenerator
     private static final String DEFAULT_INITIAL_VALUE = "1";
@@ -85,11 +87,11 @@ public class ChangedSequenceChangeGenerator
         String refValue = Objects.toString(diff.getReferenceValue(), null);
         String compValue = Objects.toString(diff.getComparedValue(), null);
 
-        if ("name".equals(field)) {
+        if (FIELD_NAME.equals(field)) {
             return isCaseInsensitiveMatch(refValue, compValue, refDb, compDb);
         }
 
-        if ("startValue".equals(field) || "incrementBy".equals(field)) {
+        if (FIELD_START_VALUE.equals(field) || 
FIELD_INCREMENT_BY.equals(field)) {
             return isDefaultOrNullMatch(refValue, compValue);
         }
 
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedUniqueConstraintChangeGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedUniqueConstraintChangeGenerator.java
index fe3aa08339..4c19cff485 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedUniqueConstraintChangeGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/ChangedUniqueConstraintChangeGenerator.java
@@ -36,7 +36,7 @@ public class ChangedUniqueConstraintChangeGenerator
         if (referenceDatabase instanceof HibernateDatabase || 
comparisonDatabase instanceof HibernateDatabase) {
             differences.removeDifference("unique");
             if (!differences.hasDifferences()) {
-                return null;
+                return new Change[0];
             }
         }
         return super.fixChanged(changedObject, differences, control, 
referenceDatabase, comparisonDatabase, chain);
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/MissingSequenceChangeGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/MissingSequenceChangeGenerator.java
index d2b53b58f6..6ada5277cb 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/MissingSequenceChangeGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/MissingSequenceChangeGenerator.java
@@ -27,9 +27,9 @@ public class MissingSequenceChangeGenerator
             Database comparisonDatabase,
             ChangeGeneratorChain chain) {
         if (referenceDatabase instanceof HibernateDatabase && 
!comparisonDatabase.supports(Sequence.class)) {
-            return null;
+            return new Change[0];
         } else if (comparisonDatabase instanceof HibernateDatabase && 
!referenceDatabase.supports(Sequence.class)) {
-            return null;
+            return new Change[0];
         } else {
             return super.fixMissing(missingObject, control, referenceDatabase, 
comparisonDatabase, chain);
         }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/UnexpectedIndexChangeGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/UnexpectedIndexChangeGenerator.java
index 7b2231a82c..960c634500 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/UnexpectedIndexChangeGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/diff/UnexpectedIndexChangeGenerator.java
@@ -31,7 +31,7 @@ public class UnexpectedIndexChangeGenerator
             Database comparisonDatabase,
             ChangeGeneratorChain chain) {
         if (referenceDatabase instanceof HibernateDatabase || 
comparisonDatabase instanceof HibernateDatabase) {
-            return null;
+            return new Change[0];
         } else {
             return super.fixUnexpected(unexpectedObject, control, 
referenceDatabase, comparisonDatabase, chain);
         }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/ColumnSnapshotGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/ColumnSnapshotGenerator.java
index fbed4db46c..b7ad3ae704 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/ColumnSnapshotGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/ColumnSnapshotGenerator.java
@@ -1,6 +1,7 @@
 package liquibase.ext.hibernate.snapshot;
 
 import java.util.List;
+import java.util.Locale;
 import java.util.Optional;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -43,7 +44,7 @@ public class ColumnSnapshotGenerator extends 
HibernateSnapshotGenerator {
             
Pattern.compile("([^\\(]*)\\s*\\(?\\s*(\\d*)?\\s*,?\\s*(\\d*)?\\s*([^\\(]*?)\\)?");
 
     public ColumnSnapshotGenerator() {
-        super(Column.class, new Class[] {Table.class});
+        super(Column.class, Table.class);
     }
 
     @Override
@@ -90,6 +91,7 @@ public class ColumnSnapshotGenerator extends 
HibernateSnapshotGenerator {
         }
     }
 
+    @SuppressWarnings("PMD.CloseResource")
     protected void snapshotColumn(Column column, DatabaseSnapshot snapshot) 
throws DatabaseException {
         HibernateDatabase database = (HibernateDatabase) 
snapshot.getDatabase();
 
@@ -214,14 +216,14 @@ public class ColumnSnapshotGenerator extends 
HibernateSnapshotGenerator {
             // so we remove any 'with time zone' suffixes here.
             // The corresponding 'with timezone' suffix will then be added 
below,
             // because in that case hibernateType also ends with 'with time 
zone'.
-            if (typeName.toLowerCase().endsWith(SQL_TIMEZONE_SUFFIX)) {
+            if 
(typeName.toLowerCase(Locale.ROOT).endsWith(SQL_TIMEZONE_SUFFIX)) {
                 typeName = typeName.substring(0, typeName.length() - 
SQL_TIMEZONE_SUFFIX.length())
                         .stripTrailing();
             }
 
             // If hibernateType ends with 'with time zone' we need to add the 
corresponding
             // 'with timezone' suffix to the Liquibase type.
-            if (hibernateType.toLowerCase().endsWith(SQL_TIMEZONE_SUFFIX)) {
+            if 
(hibernateType.toLowerCase(Locale.ROOT).endsWith(SQL_TIMEZONE_SUFFIX)) {
                 typeName += (" " + LIQUIBASE_TIMEZONE_SUFFIX);
             }
 
@@ -237,13 +239,13 @@ public class ColumnSnapshotGenerator extends 
HibernateSnapshotGenerator {
 
             String extra = StringUtil.trimToNull(matcher.group(4));
             if (extra != null) {
-                if (extra.equalsIgnoreCase("char")) {
+                if ("char".equalsIgnoreCase(extra)) {
                     dataType.setColumnSizeUnit(DataType.ColumnSizeUnit.CHAR);
                 } else {
                     if (extra.startsWith(")")) {
                         extra = extra.substring(1);
                     }
-                    extra = 
StringUtil.trimToNull(extra.toLowerCase().replace(SQL_TIMEZONE_SUFFIX, ""));
+                    extra = 
StringUtil.trimToNull(extra.toLowerCase(Locale.ROOT).replace(SQL_TIMEZONE_SUFFIX,
 ""));
                     if (extra != null) {
                         dataType.setTypeName(dataType.getTypeName() + " " + 
extra);
                     }
@@ -261,6 +263,7 @@ public class ColumnSnapshotGenerator extends 
HibernateSnapshotGenerator {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Class<? extends SnapshotGenerator>[] replaces() {
         return new Class[] 
{liquibase.snapshot.jvm.ColumnSnapshotGenerator.class};
     }
@@ -303,6 +306,6 @@ public class ColumnSnapshotGenerator extends 
HibernateSnapshotGenerator {
         if (structure.getPhysicalName() != null) {
             return structure.getPhysicalName().render();
         }
-        return (hibernateTable.getName() + "_" + hibernateColumn.getName() + 
"_seq").toLowerCase();
+        return (hibernateTable.getName() + "_" + hibernateColumn.getName() + 
"_seq").toLowerCase(Locale.ROOT);
     }
 }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/HibernateSnapshotGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/HibernateSnapshotGenerator.java
index 676026e8d7..fa75ce4805 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/HibernateSnapshotGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/HibernateSnapshotGenerator.java
@@ -1,5 +1,9 @@
 package liquibase.ext.hibernate.snapshot;
 
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+import liquibase.Scope;
 import liquibase.database.Database;
 import liquibase.exception.DatabaseException;
 import liquibase.ext.hibernate.database.HibernateDatabase;
@@ -19,22 +23,25 @@ public abstract class HibernateSnapshotGenerator implements 
SnapshotGenerator {
     private static final int PRIORITY_HIBERNATE_ADDITIONAL = 200;
     private static final int PRIORITY_HIBERNATE_DEFAULT = 100;
 
-    private Class<? extends DatabaseObject> defaultFor = null;
-    private Class<? extends DatabaseObject>[] addsTo = null;
+    private final Class<? extends DatabaseObject> defaultFor;
+    private final Class<? extends DatabaseObject>[] addsToTypes;
 
+    @SuppressWarnings("unchecked")
     protected HibernateSnapshotGenerator(Class<? extends DatabaseObject> 
defaultFor) {
-        this.defaultFor = defaultFor;
+        this(defaultFor, (Class<? extends DatabaseObject>[]) new Class[0]);
     }
 
+    @SafeVarargs
+    @SuppressWarnings("PMD.ArrayIsStoredDirectly")
     protected HibernateSnapshotGenerator(
-            Class<? extends DatabaseObject> defaultFor, Class<? extends 
DatabaseObject>[] addsTo) {
+            Class<? extends DatabaseObject> defaultFor, Class<? extends 
DatabaseObject>... addsToTypes) {
         this.defaultFor = defaultFor;
-        this.addsTo = addsTo;
+        this.addsToTypes = addsToTypes == null ? null : 
Arrays.copyOf(addsToTypes, addsToTypes.length);
     }
 
     @Override
     public Class<? extends SnapshotGenerator>[] replaces() {
-        return null;
+        return new Class[0];
     }
 
     @Override
@@ -43,8 +50,9 @@ public abstract class HibernateSnapshotGenerator implements 
SnapshotGenerator {
             if (defaultFor != null && defaultFor.isAssignableFrom(objectType)) 
{
                 return PRIORITY_HIBERNATE_DEFAULT;
             }
-            if (addsTo() != null) {
-                for (Class<? extends DatabaseObject> type : addsTo()) {
+            Class<? extends DatabaseObject>[] types = addsTo();
+            if (types != null) {
+                for (Class<? extends DatabaseObject> type : types) {
                     if (type.isAssignableFrom(objectType)) {
                         return PRIORITY_HIBERNATE_ADDITIONAL;
                     }
@@ -55,8 +63,9 @@ public abstract class HibernateSnapshotGenerator implements 
SnapshotGenerator {
     }
 
     @Override
+    @SuppressWarnings("PMD.MethodReturnsInternalArray")
     public final Class<? extends DatabaseObject>[] addsTo() {
-        return addsTo;
+        return addsToTypes == null ? null : Arrays.copyOf(addsToTypes, 
addsToTypes.length);
     }
 
     @Override
@@ -64,15 +73,15 @@ public abstract class HibernateSnapshotGenerator implements 
SnapshotGenerator {
             DatabaseObject example, DatabaseSnapshot snapshot, 
SnapshotGeneratorChain chain)
             throws DatabaseException, InvalidExampleException {
         if (defaultFor != null && 
defaultFor.isAssignableFrom(example.getClass())) {
-            DatabaseObject result = snapshotObject(example, snapshot);
-            return result;
+            return snapshotObject(example, snapshot);
         }
         DatabaseObject chainResponse = chain.snapshot(example, snapshot);
         if (chainResponse == null) {
             return null;
         }
-        if (addsTo() != null) {
-            for (Class<? extends DatabaseObject> addType : addsTo()) {
+        Class<? extends DatabaseObject>[] types = addsTo();
+        if (types != null) {
+            for (Class<? extends DatabaseObject> addType : types) {
                 if (addType.isAssignableFrom(example.getClass())) {
                     addTo(chainResponse, snapshot);
                 }
@@ -87,6 +96,7 @@ public abstract class HibernateSnapshotGenerator implements 
SnapshotGenerator {
     protected abstract void addTo(DatabaseObject foundObject, DatabaseSnapshot 
snapshot)
             throws DatabaseException, InvalidExampleException;
 
+    @SuppressWarnings("PMD.CloseResource")
     protected org.hibernate.mapping.Table findHibernateTable(DatabaseObject 
example, DatabaseSnapshot snapshot) {
         Metadata metadata = null;
         Database database = snapshot.getDatabase();
@@ -94,9 +104,10 @@ public abstract class HibernateSnapshotGenerator implements 
SnapshotGenerator {
             metadata = hibernateDatabase.getMetadata();
         } else {
             try {
-                metadata = (Metadata) 
database.getClass().getMethod("getMetadata").invoke(database);
+                Method getMetadata = 
database.getClass().getMethod("getMetadata");
+                metadata = (Metadata) getMetadata.invoke(database);
             } catch (Exception e) {
-                // not a metadata-bearing database
+                Scope.getCurrentScope().getLog(getClass()).debug("Error 
getting metadata from database", e);
             }
         }
 
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/IndexSnapshotGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/IndexSnapshotGenerator.java
index 3976e78eb9..8602dac320 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/IndexSnapshotGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/IndexSnapshotGenerator.java
@@ -12,10 +12,10 @@ public class IndexSnapshotGenerator extends 
HibernateSnapshotGenerator {
 
     private static final String HIBERNATE_ORDER_ASC = "asc";
     private static final String HIBERNATE_ORDER_DESC = "desc";
+    private static final int SINGLE_COLUMN = 1;
 
-    @SuppressWarnings("unchecked")
     public IndexSnapshotGenerator() {
-        super(Index.class, new Class[] {Table.class, ForeignKey.class, 
UniqueConstraint.class});
+        super(Index.class, Table.class, ForeignKey.class, 
UniqueConstraint.class);
     }
 
     @Override
@@ -83,7 +83,7 @@ public class IndexSnapshotGenerator extends 
HibernateSnapshotGenerator {
         This seems to be necessary to explicitly tell liquibase that there's no
         actual diff in certain non-unique indexes
         */
-        if (hibernateIndex.getColumnSpan() == 1) {
+        if (hibernateIndex.getColumnSpan() == SINGLE_COLUMN) {
             var col = ((org.hibernate.mapping.Column)
                     hibernateIndex.getSelectables().get(0));
             return col.isUnique();
@@ -94,11 +94,12 @@ public class IndexSnapshotGenerator extends 
HibernateSnapshotGenerator {
             and the value read from the database is 'false', resulting in the 
generated changeSet after the Drop and
             Recreate Index.
             */
-            return false;
+            return Boolean.FALSE;
         }
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Class<? extends SnapshotGenerator>[] replaces() {
         return new Class[] 
{liquibase.snapshot.jvm.IndexSnapshotGenerator.class};
     }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/SequenceSnapshotGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/SequenceSnapshotGenerator.java
index 3b6e6e32d4..c26e24299f 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/SequenceSnapshotGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/SequenceSnapshotGenerator.java
@@ -17,7 +17,7 @@ import liquibase.structure.core.Sequence;
 public class SequenceSnapshotGenerator extends HibernateSnapshotGenerator {
 
     public SequenceSnapshotGenerator() {
-        super(Sequence.class, new Class[] {Schema.class});
+        super(Sequence.class, Schema.class);
     }
 
     @Override
@@ -27,6 +27,7 @@ public class SequenceSnapshotGenerator extends 
HibernateSnapshotGenerator {
     }
 
     @Override
+    @SuppressWarnings("PMD.CloseResource")
     protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot)
             throws DatabaseException, InvalidExampleException {
         if (!snapshot.getSnapshotControl().shouldInclude(Sequence.class)) {
@@ -49,6 +50,7 @@ public class SequenceSnapshotGenerator extends 
HibernateSnapshotGenerator {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Class<? extends SnapshotGenerator>[] replaces() {
         return new Class[] 
{liquibase.snapshot.jvm.SequenceSnapshotGenerator.class};
     }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/TableSnapshotGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/TableSnapshotGenerator.java
index 27f33d42c3..04fd9baaf7 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/TableSnapshotGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/TableSnapshotGenerator.java
@@ -16,7 +16,7 @@ import org.hibernate.mapping.*;
 public class TableSnapshotGenerator extends HibernateSnapshotGenerator {
 
     public TableSnapshotGenerator() {
-        super(Table.class, new Class[] {Schema.class});
+        super(Table.class, Schema.class);
     }
 
     @Override
@@ -41,6 +41,7 @@ public class TableSnapshotGenerator extends 
HibernateSnapshotGenerator {
     }
 
     @Override
+    @SuppressWarnings("PMD.CloseResource")
     protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot)
             throws DatabaseException, InvalidExampleException {
         if (!snapshot.getSnapshotControl().shouldInclude(Table.class)) {
@@ -83,6 +84,7 @@ public class TableSnapshotGenerator extends 
HibernateSnapshotGenerator {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Class<? extends SnapshotGenerator>[] replaces() {
         return new Class[] 
{liquibase.snapshot.jvm.TableSnapshotGenerator.class};
     }
diff --git 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/UniqueConstraintSnapshotGenerator.java
 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/UniqueConstraintSnapshotGenerator.java
index 229551119c..3b1c54cd59 100644
--- 
a/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/UniqueConstraintSnapshotGenerator.java
+++ 
b/grails-data-hibernate7/dbmigration/src/main/java/liquibase/ext/hibernate/snapshot/UniqueConstraintSnapshotGenerator.java
@@ -3,6 +3,7 @@ package liquibase.ext.hibernate.snapshot;
 import java.math.BigInteger;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.Locale;
 
 import liquibase.Scope;
 import liquibase.exception.DatabaseException;
@@ -19,8 +20,13 @@ import org.hibernate.HibernateException;
 
 public class UniqueConstraintSnapshotGenerator extends 
HibernateSnapshotGenerator {
 
+    private static final int MAX_NAME_LENGTH = 64;
+    private static final int SHORTENED_NAME_LENGTH = 63;
+    private static final int START_INDEX = 0;
+    private static final int FIRST_COLUMN = 0;
+
     public UniqueConstraintSnapshotGenerator() {
-        super(UniqueConstraint.class, new Class[] {Table.class});
+        super(UniqueConstraint.class, Table.class);
     }
 
     @Override
@@ -45,7 +51,7 @@ public class UniqueConstraintSnapshotGenerator extends 
HibernateSnapshotGenerato
                 var uniqueConstraint = new UniqueConstraint();
                 uniqueConstraint.setName(hibernateUnique.getName());
                 uniqueConstraint.setRelation(table);
-                uniqueConstraint.setClustered(false); // No way to set true 
via Hibernate
+                uniqueConstraint.setClustered(Boolean.FALSE); // No way to set 
true via Hibernate
 
                 int i = 0;
                 for (var hibernateColumn : hibernateUnique.getColumns()) {
@@ -62,13 +68,13 @@ public class UniqueConstraintSnapshotGenerator extends 
HibernateSnapshotGenerato
                 if (column.isUnique()) {
                     UniqueConstraint uniqueConstraint = new UniqueConstraint();
                     uniqueConstraint.setRelation(table);
-                    uniqueConstraint.setClustered(false); // No way to set 
true via Hibernate
-                    String name = "UC_" + table.getName().toUpperCase()
-                            + column.getName().toUpperCase() + "_COL";
-                    if (name.length() > 64) {
-                        name = name.substring(0, 63);
+                    uniqueConstraint.setClustered(Boolean.FALSE); // No way to 
set true via Hibernate
+                    String name = "UC_" + 
table.getName().toUpperCase(Locale.ROOT)
+                            + column.getName().toUpperCase(Locale.ROOT) + 
"_COL";
+                    if (name.length() > MAX_NAME_LENGTH) {
+                        name = name.substring(START_INDEX, 
SHORTENED_NAME_LENGTH);
                     }
-                    uniqueConstraint.addColumn(0, new 
Column(column.getName()).setRelation(table));
+                    uniqueConstraint.addColumn(FIRST_COLUMN, new 
Column(column.getName()).setRelation(table));
                     uniqueConstraint.setName(name);
                     Scope.getCurrentScope().getLog(getClass()).info("Found 
unique constraint " + uniqueConstraint);
                     table.getUniqueConstraints().add(uniqueConstraint);
@@ -116,6 +122,7 @@ public class UniqueConstraintSnapshotGenerator extends 
HibernateSnapshotGenerato
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Class<? extends SnapshotGenerator>[] replaces() {
         return new Class[] 
{liquibase.snapshot.jvm.UniqueConstraintSnapshotGenerator.class};
     }


Reply via email to