You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@grails.apache.org by bo...@apache.org on 2026/03/23 01:53:09 UTC
(grails-core) 04/08: hibernate 7: Internally DataSource Connection.DEFAULT value was incorrect, still support legacy value hardcoded
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
commit 0d2c60704c50b80d863e05a3a118e158551ce259
Author: Walter Duque de Estrada <wb...@mac.com>
AuthorDate: Sun Mar 22 13:25:05 2026 -0500
hibernate 7: Internally DataSource Connection.DEFAULT value was incorrect, still support legacy value hardcoded
---
grails-data-hibernate7/core/ISSUES.md | 98 ++++++++++++++++++++++
.../orm/hibernate/GrailsHibernateTemplate.java | 17 ++--
.../grails/orm/hibernate/HibernateDatastore.java | 51 ++++++-----
.../domainbinding/binder/GrailsDomainBinder.java | 3 +-
.../hibernate/GrailsHibernatePersistentEntity.java | 49 +++++------
.../util/MultiTenantFilterBinder.java | 3 +-
.../HibernateConnectionSourceFactory.java | 15 ++--
.../proxy/GroovyProxyInterceptorLogic.java | 26 +++---
.../grails/orm/hibernate/query/HibernateAlias.java | 18 +---
.../orm/hibernate/query/HqlQueryContext.java | 42 +++++-----
.../orm/hibernate/query/JpaFromProvider.java | 2 +-
.../orm/hibernate/HibernateDatastoreSpec.groovy | 77 ++++++++++++++---
.../cfg/GrailsHibernatePersistentEntitySpec.groovy | 3 +-
.../cfg/HibernateMappingContextSpec.groovy | 5 +-
.../cfg/domainbinding/binder/RootBinderSpec.groovy | 7 +-
.../domainbinding/binder/SubClassBinderSpec.groovy | 10 +--
.../mapping/core/connections/ConnectionSource.java | 9 +-
.../datastore/mapping/model/MappingContext.java | 2 +-
18 files changed, 294 insertions(+), 143 deletions(-)
diff --git a/grails-data-hibernate7/core/ISSUES.md b/grails-data-hibernate7/core/ISSUES.md
index 524d83cb6d..e9194b2bc3 100644
--- a/grails-data-hibernate7/core/ISSUES.md
+++ b/grails-data-hibernate7/core/ISSUES.md
@@ -1,7 +1,105 @@
# Known Issues in Hibernate 7 Migration
+## [TODO] Review impact of changing `ConnectionSource.DEFAULT` to "default"
+**Description:**
+The value of `ConnectionSource.DEFAULT` was changed from `"DEFAULT"` to `"default"` (lowercase) to align with Grails 7 official conventions.
+A new constant `ConnectionSource.OLD_DEFAULT = "DEFAULT"` was added for backward compatibility.
+In Grails 7:
+- GORM Connection Name: `"default"` (via `ConnectionSource.DEFAULT`)
+- Spring Bean ID: `"dataSource"`
+- Configuration Key: `"dataSource"`
+**Actions taken in H7:**
+- `HibernateDatastore.getDatastoreForConnection` supports `"dataSource"`, `ConnectionSource.DEFAULT` ("default"), and `ConnectionSource.OLD_DEFAULT` ("DEFAULT").
+- Raw `"default"` and `"DEFAULT"` strings in H7 production code and key tests have been replaced with `ConnectionSource.DEFAULT`.
+- `HibernateMappingContextConfiguration` and `HibernateDatastore` correctly use `ConnectionSource.DEFAULT` for the primary datasource name.
+**Risk & Potential Propagation:**
+- This change might affect other GORM modules (Neo4j, MongoDB, etc.) if they rely on the uppercase `"DEFAULT"` string literal and don't yet support the lowercase `"default"`.
+- Production systems referencing the raw string `"DEFAULT"` should be encouraged to use the `ConnectionSource.DEFAULT` constant.
+**Action Required:**
+- Audit other GORM implementations for consistency.
+
+## Static Analysis Violations (hibernate7-core)
+
+### Checkstyle
+| Class | Line | Error |
+|-------|------|-------|
+| `org.grails.orm.hibernate.proxy.HibernateProxyHandler` | 119-121 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.proxy.ByteBuddyGroovyInterceptor` | 67 | '+' should be on the previous line. |
+| `org.grails.orm.hibernate.proxy.ByteBuddyGroovyInterceptor` | 71-72 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.proxy.GroovyProxyInterceptorLogic` | 44 | '&&' should be on the previous line. |
+| `org.grails.orm.hibernate.proxy.GroovyProxyInterceptorLogic` | 64-67 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.access.TraitPropertyAccessStrategy` | 72 | '&&' should be on the previous line. |
+| `org.grails.orm.hibernate.access.TraitPropertyAccessStrategy` | 73 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.access.TraitPropertyAccessStrategy` | 80-113 | '+' should be on the previous line. (Multiple occurrences) |
+| `org.grails.orm.hibernate.HibernateDatastore` | 34 | 'javax.sql.DataSource' should be separated from previous imports. |
+| `org.grails.orm.hibernate.HibernateDatastore` | 332 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.HibernateDatastore` | 339-823 | '+' should be on the previous line. (Multiple occurrences) |
+| `org.grails.orm.hibernate.HibernateDatastore` | 927 | '?' should be on the previous line. |
+| `org.grails.orm.hibernate.HibernateDatastore` | 928 | ':' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.TableForManyCalculator` | 81 | '+' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.NamingStrategyProvider` | 92 | '?' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.NamingStrategyProvider` | 93 | ':' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher` | 27 | '?' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.SimpleValueColumnFetcher` | 28 | ':' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator` | 73 | '?' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.BasicValueIdCreator` | 75 | ':' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.CascadeBehavior` | 107 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher` | 69-81 | '+' should be on the previous line. (Multiple occurrences) |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder` | 107-108 | '||' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.OrderByClauseBuilder` | 109 | '&&' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.util.ColumnNameForPropertyAndPathFetcher` | 52-53 | '+' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.ColumnBinder` | 130-149 | '+' should be on the previous line. (Multiple occurrences) |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.JoinedSubClassBinder` | 93-94 | '+' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder` | 105 | '?' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueBinder` | 107 | ':' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.UnionSubclassBinder` | 89-90 | '+' should be on the previous line. |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.ForeignKeyOneToOneBinder` | 71 | '&&' should be on the previous line. |
+
+### PMD
+| Class | Line | Error | Rule |
+|-------|------|-------|------|
+| `org.grails.orm.hibernate.GrailsHibernateTemplate` | 341 | New exception is thrown in catch block, original stack trace may be lost | PreserveStackTrace |
+| `org.grails.orm.hibernate.HibernateDatastore` | 661 | Avoid using Literals in Conditional Statements | AvoidLiteralsInIfCondition |
+| `org.grails.orm.hibernate.cfg.GrailsHibernateUtil` | 274 | Position literals first in String comparisons | LiteralsFirstInComparisons |
+| `org.grails.orm.hibernate.cfg.GrailsHibernateUtil` | 292 | Logger calls should be surrounded by log level guards. | GuardLogStatement |
+| `org.grails.orm.hibernate.cfg.GrailsHibernateUtil` | 294 | Logger calls should be surrounded by log level guards. | GuardLogStatement |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContext` | 123 | Avoid reassigning parameters such as 'name' | AvoidReassigningParameters |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 106 | Field 'hibernateMappingContext' is of non-serializable type | NonSerializableClass |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 108 | Field 'hibernateEventListeners' is of non-serializable type | NonSerializableClass |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 114 | Field 'namingStrategyProvider' is of non-serializable type | NonSerializableClass |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 146 | The String literal "false" appears 5 times in this file | AvoidDuplicateLiterals |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 187 | The method 'addAnnotatedClasses(Class...)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 207 | The method 'addPackages(String...)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | 348 | The method 'sessionFactoryClosed(SessionFactory)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.IdentityEnumType$BidiEnumMap` | 203 | Logger calls should be surrounded by log level guards. | GuardLogStatement |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.ComponentBinder` | 69 | Avoid unused local variables such as 'table'. | UnusedLocalVariable |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.CompositeIdBinder` | 78 | Avoid unused local variables such as 'table'. | UnusedLocalVariable |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.EnumTypeBinder` | 107 | Switch statements should be exhaustive, add a default case | SwitchStmtsShouldHaveDefault |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.RootBinder` | 75 | Logger calls should be surrounded by log level guards. | GuardLogStatement |
+| `org.grails.orm.hibernate.cfg.domainbinding.binder.SimpleValueColumnBinder` | 36 | Avoid unused constructor parameters such as 'ignore'. | UnusedFormalParameter |
+| `org.grails.orm.hibernate.cfg.domainbinding.generator.GrailsNativeGenerator` | 73 | You should not modify visibility using setAccessible() | AvoidAccessibilityAlteration |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersistentEntity` | 50 | The method 'getMappedForm()' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateAssociation` | 89 | The method 'isBidirectionalManyToOneWithListMapping(Property)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateAssociation` | 103 | The method 'getTypeName(Class, PropertyConfig, Mapping)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateBasicProperty` | 38 | The method 'getCollection()' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateBasicProperty` | 42 | The method 'setCollection(Collection)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedCollectionProperty` | 43 | The method 'getCollection()' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedCollectionProperty` | 47 | The method 'setCollection(Collection)' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedPersistentEntity` | 35 | The method 'getMappedForm()' is missing an @Override annotation. | MissingOverride |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateIdentityMapping` | 60 | Returning 'DEFAULT_IDENTITY_MAPPING' may expose an internal array. | MethodReturnsInternalArray |
+| `org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateManyToManyProperty` | 44 | The method 'getReferencedEntityName()' is missing an @Override annotation. | MissingOverride |
+
+### SpotBugs
+| Class | Line | Error | Bug Type |
+|-------|------|-------|----------|
+| `org.grails.orm.hibernate.query.PagedResultList` | 50-93 | Class shadows the simple name of the superclass | NM_SAME_SIMPLE_NAME_AS_SUPERCLASS |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | N/A | Non-serializable field `hibernateEventListeners` | SE_BAD_FIELD |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | N/A | Non-serializable field `hibernateMappingContext` | SE_BAD_FIELD |
+| `org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration` | N/A | Non-serializable field `namingStrategyProvider` | SE_BAD_FIELD |
+| `org.grails.orm.hibernate.proxy.ByteBuddyGroovyInterceptor` | N/A | Potential null pointer dereference in proxy logic | NP_NULL_ON_SOME_PATH |
+| `org.grails.orm.hibernate.proxy.ByteBuddyGroovyProxyFactory` | N/A | Class implements Serializable but doesn't define serialVersionUID | SE_NO_SERIALVERSIONID |
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
index d44afc3747..60049f9100 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/GrailsHibernateTemplate.java
@@ -26,7 +26,6 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
-
import javax.sql.DataSource;
import groovy.lang.Closure;
@@ -148,7 +147,8 @@ public class GrailsHibernateTemplate implements IHibernateTemplate {
@Override
public <T> T execute(Closure<T> callable) {
- HibernateCallback<T> hibernateCallback = DefaultGroovyMethods.asType(callable, HibernateCallback.class);
+ @SuppressWarnings("unchecked")
+ HibernateCallback<T> hibernateCallback = (HibernateCallback<T>) DefaultGroovyMethods.asType(callable, HibernateCallback.class);
return execute(hibernateCallback);
}
@@ -207,8 +207,8 @@ public class GrailsHibernateTemplate implements IHibernateTemplate {
(ConnectionHolder) TransactionSynchronizationManager.unbindResourceIfPossible(dataSource);
// if there is a connection holder and it holds an open connection close it
try {
- if (connectionHolder != null &&
- !connectionHolder.getConnection().isClosed()) {
+ if (connectionHolder != null
+ && !connectionHolder.getConnection().isClosed()) {
Connection conn = connectionHolder.getConnection();
DataSourceUtils.releaseConnection(conn, dataSource);
}
@@ -216,8 +216,8 @@ public class GrailsHibernateTemplate implements IHibernateTemplate {
// ignore, connection closed already?
if (LOG.isDebugEnabled()) {
LOG.debug(
- "Could not close opened JDBC connection. Did the application close the connection manually?: " +
- e.getMessage());
+ "Could not close opened JDBC connection. Did the application close the connection manually?: "
+ + e.getMessage());
}
}
} finally {
@@ -284,8 +284,8 @@ public class GrailsHibernateTemplate implements IHibernateTemplate {
}
protected boolean shouldPassReadOnlyToHibernate() {
- if ((passReadOnlyToHibernate || osivReadOnly) &&
- TransactionSynchronizationManager.hasResource(getSessionFactory())) {
+ if ((passReadOnlyToHibernate || osivReadOnly)
+ && TransactionSynchronizationManager.hasResource(getSessionFactory())) {
if (TransactionSynchronizationManager.isActualTransactionActive()) {
return passReadOnlyToHibernate && TransactionSynchronizationManager.isCurrentTransactionReadOnly();
} else {
@@ -338,6 +338,7 @@ public class GrailsHibernateTemplate implements IHibernateTemplate {
throw convertHibernateAccessException(ex);
} catch (PersistenceException ex) {
if (ex.getCause() instanceof HibernateException) {
+ // @SuppressWarnings("PMD.PreserveStackTrace")
throw SessionFactoryUtils.convertHibernateAccessException((HibernateException) ex.getCause());
}
throw ex;
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateDatastore.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateDatastore.java
index 07f32bf806..23262b6a9b 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateDatastore.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/HibernateDatastore.java
@@ -31,7 +31,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Callable;
-
import javax.sql.DataSource;
import groovy.lang.Closure;
@@ -109,7 +108,6 @@ import org.grails.datastore.mapping.multitenancy.resolvers.FixedTenantResolver;
import org.grails.datastore.mapping.transactions.TransactionCapableDatastore;
import org.grails.datastore.mapping.validation.ValidatorRegistry;
import org.grails.orm.hibernate.cfg.HibernateMappingContext;
-import org.grails.orm.hibernate.cfg.MappingCacheHolder;
import org.grails.orm.hibernate.cfg.Settings;
import org.grails.orm.hibernate.connections.HibernateConnectionSource;
import org.grails.orm.hibernate.connections.HibernateConnectionSourceFactory;
@@ -219,7 +217,7 @@ public class HibernateDatastore extends AbstractDatastore
this.connectionSources = connectionSources;
final HibernateConnectionSource defaultConnectionSource =
(HibernateConnectionSource) connectionSources.getDefaultConnectionSource();
- this.dataSourceName = defaultConnectionSource.getName();
+ this.dataSourceName = ConnectionSource.DEFAULT;
this.sessionFactory = defaultConnectionSource.getSource();
HibernateConnectionSourceSettings settings = defaultConnectionSource.getSettings();
HibernateConnectionSourceSettings.HibernateSettings hibernateSettings = settings.getHibernate();
@@ -330,16 +328,15 @@ public class HibernateDatastore extends AbstractDatastore
@Override
public HibernateDatastore getDatastoreForConnection(String connectionName) {
- if (connectionName.equals(Settings.SETTING_DATASOURCE) ||
- connectionName.equals(ConnectionSource.DEFAULT)) {
+ if (Settings.SETTING_DATASOURCE.equals(connectionName)
+ || ConnectionSource.DEFAULT.equals(connectionName)) {
return parent;
} else {
HibernateDatastore hibernateDatastore = parent.datastoresByConnectionSource.get(connectionName);
if (hibernateDatastore == null) {
throw new ConfigurationException(
- "DataSource not found for name [" +
- connectionName +
- "] in configuration. Please check your multiple data sources configuration and try again.");
+ "DataSource not found for name [" + connectionName
+ + "] in configuration. Please check your multiple data sources configuration and try again.");
}
return hibernateDatastore;
}
@@ -576,6 +573,7 @@ public class HibernateDatastore extends AbstractDatastore
/**
* @return The {@link org.springframework.transaction.PlatformTransactionManager} instance
*/
+ @Override
public GrailsHibernateTransactionManager getTransactionManager() {
return transactionManager;
}
@@ -588,14 +586,15 @@ public class HibernateDatastore extends AbstractDatastore
*/
@Override
public HibernateDatastore getDatastoreForConnection(String connectionName) {
- if (Settings.SETTING_DATASOURCE.equals(connectionName) || ConnectionSource.DEFAULT.equals(connectionName)) {
+ if (Settings.SETTING_DATASOURCE.equals(connectionName)
+ || ConnectionSource.DEFAULT.equals(connectionName)
+ || ConnectionSource.OLD_DEFAULT.equals(connectionName)) {
return this;
} else {
HibernateDatastore hibernateDatastore = this.datastoresByConnectionSource.get(connectionName);
if (hibernateDatastore == null) {
- throw new ConfigurationException("DataSource not found for name [" +
- connectionName +
- "] in configuration. Please check your multiple data sources configuration and try again.");
+ throw new ConfigurationException("DataSource not found for name [" + connectionName
+ + "] in configuration. Please check your multiple data sources configuration and try again.");
}
return hibernateDatastore;
}
@@ -661,7 +660,7 @@ public class HibernateDatastore extends AbstractDatastore
schemaHandler.resolveSchemaNames(defaultConnectionSource.getDataSource());
for (String schemaName : schemaNames) {
// skip common internal schemas
- if (schemaName.equals("INFORMATION_SCHEMA") || schemaName.equals("PUBLIC")) continue;
+ if ("INFORMATION_SCHEMA".equals(schemaName) || "PUBLIC".equals(schemaName)) continue;
for (String connectionName : datastoresByConnectionSource.keySet()) {
if (schemaName.equalsIgnoreCase(connectionName)) {
allQualifiers.add(connectionName);
@@ -689,6 +688,7 @@ public class HibernateDatastore extends AbstractDatastore
return new HibernateSession(this, sessionFactory);
}
+ @Override
public void setApplicationContext(@Nullable ApplicationContext applicationContext) throws BeansException {
if (applicationContext instanceof ConfigurableApplicationContext) {
super.setApplicationContext(applicationContext);
@@ -764,7 +764,9 @@ public class HibernateDatastore extends AbstractDatastore
try {
connectionSources.close();
} catch (IOException e) {
- LOG.error("There was an error shutting down GORM for an entity: {}", e.getMessage(), e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("There was an error shutting down GORM for an entity: {}", e.getMessage(), e);
+ }
}
} finally {
getMappingContext().getMappingCacheHolder().clear();
@@ -773,7 +775,9 @@ public class HibernateDatastore extends AbstractDatastore
this.gormEnhancer.close();
}
} catch (IOException e) {
- LOG.error("There was an error shutting down GORM enhancer", e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("There was an error shutting down GORM enhancer", e);
+ }
}
destroyed = true;
}
@@ -817,16 +821,15 @@ public class HibernateDatastore extends AbstractDatastore
private void addTenantForSchemaInternal(final String schemaName) {
if (multiTenantMode != MultiTenancySettings.MultiTenancyMode.SCHEMA) {
throw new ConfigurationException(
- "The method [addTenantForSchema] can only be called with multi-tenancy mode SCHEMA. Current mode is: " +
- multiTenantMode);
+ "The method [addTenantForSchema] can only be called with multi-tenancy mode SCHEMA. Current mode is: "
+ + multiTenantMode);
}
HibernateConnectionSourceFactory factory = (HibernateConnectionSourceFactory) connectionSources.getFactory();
HibernateConnectionSource defaultConnectionSource =
(HibernateConnectionSource) connectionSources.getDefaultConnectionSource();
HibernateConnectionSourceSettings tenantSettings;
try {
- tenantSettings = (HibernateConnectionSourceSettings)
- connectionSources.getDefaultConnectionSource().getSettings().clone();
+ tenantSettings = (HibernateConnectionSourceSettings) connectionSources.getDefaultConnectionSource().getSettings().clone();
} catch (CloneNotSupportedException e) {
throw new ConfigurationException("Couldn't clone default Hibernate settings! " + e.getMessage(), e);
}
@@ -921,9 +924,9 @@ public class HibernateDatastore extends AbstractDatastore
@Override
public MultiTenancySettings.MultiTenancyMode getMultiTenancyMode() {
- return this.multiTenantMode == MultiTenancySettings.MultiTenancyMode.SCHEMA ?
- MultiTenancySettings.MultiTenancyMode.DATABASE :
- this.multiTenantMode;
+ return this.multiTenantMode == MultiTenancySettings.MultiTenancyMode.SCHEMA
+ ? MultiTenancySettings.MultiTenancyMode.DATABASE
+ : this.multiTenantMode;
}
@Override
@@ -1111,7 +1114,9 @@ public class HibernateDatastore extends AbstractDatastore
try {
destroy();
} catch (Exception e) {
- LOG.error("Error closing hibernate datastore: {}", e.getMessage(), e);
+ if (LOG.isErrorEnabled()) {
+ LOG.error("Error closing hibernate datastore: {}", e.getMessage(), e);
+ }
}
}
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
index f16f5cd717..eabaa2d192 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/GrailsDomainBinder.java
@@ -18,6 +18,7 @@
*/
package org.grails.orm.hibernate.cfg.domainbinding.binder;
+import org.grails.datastore.mapping.core.connections.ConnectionSource;
import org.hibernate.boot.ResourceStreamLocator;
import org.hibernate.boot.internal.MetadataBuildingContextRootImpl;
import org.hibernate.boot.model.TypeContributions;
@@ -116,7 +117,7 @@ public class GrailsDomainBinder implements AdditionalMappingContributor, TypeCon
ResourceStreamLocator resourceStreamLocator,
MetadataBuildingContext buildingContext) {
this.metadataBuildingContext = new MetadataBuildingContextRootImpl(
- "default",
+ ConnectionSource.DEFAULT,
metadataCollector.getBootstrapContext(),
metadataCollector.getMetadataBuildingOptions(),
metadataCollector,
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
index 84f119d6a1..e85c6e4f38 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/GrailsHibernatePersistentEntity.java
@@ -28,6 +28,7 @@ import java.util.stream.Stream;
import jakarta.annotation.Nonnull;
+import org.hibernate.FetchMode;
import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.mapping.PersistentClass;
@@ -233,9 +234,7 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
}
default List<HibernatePersistentEntity> getChildEntities(String dataSourceName) {
- return getMappingContext()
- .getDirectChildEntities(this)
- .stream()
+ return getMappingContext().getDirectChildEntities(this).stream()
.filter(HibernatePersistentEntity.class::isInstance)
.map(HibernatePersistentEntity.class::cast)
.filter(persistentEntity -> persistentEntity.usesConnectionSource(dataSourceName))
@@ -301,9 +300,9 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
}
private static String resolveDiscriminatorValue(DiscriminatorConfig discriminatorConfig) {
- return discriminatorConfig.getColumn() != null ?
- discriminatorConfig.getColumn().getName() :
- discriminatorConfig.getFormula();
+ return discriminatorConfig.getColumn() != null
+ ? discriminatorConfig.getColumn().getName()
+ : discriminatorConfig.getFormula();
}
default List<HibernatePersistentProperty> getHibernatePersistentProperties() {
@@ -312,12 +311,13 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
.map(HibernatePersistentProperty.class::cast)
.toList());
properties.sort((p1, p2) -> {
- if (p1 instanceof org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty &&
- !(p2 instanceof
- org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty)) {
+ if (p1 instanceof org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty
+ && !(p2
+ instanceof
+ org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty)) {
return -1;
- } else if (!(p1 instanceof org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty) &&
- p2 instanceof org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty) {
+ } else if (!(p1 instanceof org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty)
+ && p2 instanceof org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernateEmbeddedProperty) {
return 1;
}
return p1.getName().compareTo(p2.getName());
@@ -348,23 +348,14 @@ public interface GrailsHibernatePersistentEntity extends PersistentEntity {
return false;
}
- org.grails.orm.hibernate.cfg.PropertyConfig config = property.getMappedForm();
-
- if (property instanceof HibernateAssociation) {
- // Explicit fetch: 'join' implies eager (not lazy) and takes precedence in Hibernate
- if (config != null && org.hibernate.FetchMode.JOIN.equals(config.getFetchMode())) {
- return false;
- }
- if (config != null && config.getLazy() != null) {
- return config.getLazy();
- }
- return true;
- }
-
- if (config != null && config.getLazy() != null) {
- return config.getLazy();
- }
-
- return false;
+ return Optional.ofNullable(property.getMappedForm())
+ .map(config -> {
+ if (property instanceof HibernateAssociation &&
+ FetchMode.JOIN.equals(config.getFetchMode())) {
+ return false;
+ }
+ return config.getLazy();
+ })
+ .orElseGet(() -> property instanceof HibernateAssociation);
}
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java
index 0d332dd5b2..9ae540fb11 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/util/MultiTenantFilterBinder.java
@@ -81,8 +81,7 @@ public class MultiTenantFilterBinder {
* @return null as it's redundant for single table subclasses
*/
@Nullable
- public FilterDefinition bind(
- @Nonnull HibernatePersistentEntity entity, @Nonnull SingleTableSubclass subclass) {
+ public FilterDefinition bind(@Nonnull HibernatePersistentEntity entity, @Nonnull SingleTableSubclass subclass) {
return null; // Redundant for SingleTableSubclass
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/connections/HibernateConnectionSourceFactory.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/connections/HibernateConnectionSourceFactory.java
index 52e126bfe3..a8695cdd47 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/connections/HibernateConnectionSourceFactory.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/connections/HibernateConnectionSourceFactory.java
@@ -23,7 +23,6 @@ import java.io.IOException;
import java.io.Serializable;
import java.util.Collections;
import java.util.Map;
-
import javax.sql.DataSource;
import jakarta.annotation.Nullable;
@@ -57,7 +56,6 @@ import org.grails.orm.hibernate.HibernateEventListeners;
import org.grails.orm.hibernate.cfg.HibernateMappingContext;
import org.grails.orm.hibernate.cfg.HibernateMappingContextConfiguration;
import org.grails.orm.hibernate.cfg.Settings;
-import org.grails.orm.hibernate.cfg.domainbinding.binder.GrailsDomainBinder;
import org.grails.orm.hibernate.support.ClosureEventTriggeringInterceptor;
/**
@@ -145,11 +143,12 @@ public class HibernateConnectionSourceFactory
resolveEventTriggeringInterceptor(hibernateSettings.getClosureEventTriggeringInterceptorClass());
hibernateSettings.setEventTriggeringInterceptor(eventTriggeringInterceptor);
- configuration.setEventListeners(hibernateSettings.toHibernateEventListeners(eventTriggeringInterceptor));
+ configuration.setEventListeners(HibernateConnectionSourceSettings.HibernateSettings.toHibernateEventListeners(
+ eventTriggeringInterceptor));
configuration.setHibernateEventListeners(
- this.hibernateEventListeners != null ?
- this.hibernateEventListeners :
- hibernateSettings.getHibernateEventListeners());
+ this.hibernateEventListeners != null
+ ? this.hibernateEventListeners
+ : hibernateSettings.getHibernateEventListeners());
configuration.setHibernateMappingContext(mappingContext);
configuration.setDataSourceName(name);
configuration.setSessionFactoryBeanName(
@@ -288,8 +287,8 @@ public class HibernateConnectionSourceFactory
DataSourceSettings dsFallback = extractDataSourceFallback(fallbackSettings);
HibernateConnectionSourceSettings settings =
new HibernateConnectionSourceSettingsBuilder(configuration, prefix, fallbackSettings).build();
- if (prefix.isEmpty() ||
- configuration
+ if (prefix.isEmpty()
+ || configuration
.getProperty(prefix + ".dataSource", Map.class, Collections.emptyMap())
.isEmpty()) {
settings.setDataSource(new DataSourceSettingsBuilder(configuration, prefix, dsFallback).build());
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/proxy/GroovyProxyInterceptorLogic.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/proxy/GroovyProxyInterceptorLogic.java
index c972745ca5..2a7b9c9b89 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/proxy/GroovyProxyInterceptorLogic.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/proxy/GroovyProxyInterceptorLogic.java
@@ -24,6 +24,7 @@ import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.HandleMetaClass;
import org.codehaus.groovy.runtime.InvokerHelper;
+
import org.grails.datastore.gorm.proxy.ProxyInstanceMetaClass;
/**
@@ -36,35 +37,34 @@ public class GroovyProxyInterceptorLogic {
public static final Object INVOKE_IMPLEMENTATION = new Object();
- public record InterceptorState(
- String entityName,
- Class<?> persistentClass,
- Object identifier
- ) {}
+ public record InterceptorState(String entityName, Class<?> persistentClass, Object identifier) {}
public static Object handleUninitialized(InterceptorState state, String methodName, Object[] args) {
- if ((methodName.equals("getMetaClass") || methodName.endsWith("getStaticMetaClass")) && (args == null || args.length == 0)) {
+ if (("getMetaClass".equals(methodName) || methodName.endsWith("getStaticMetaClass"))
+ && (args == null || args.length == 0)) {
return InvokerHelper.getMetaClass(state.persistentClass());
}
- if (methodName.equals("getProperty") && args.length == 1 && args[0].equals("id")) {
+ if ("getProperty".equals(methodName) && args.length == 1 && "id".equals(args[0])) {
return state.identifier();
}
- if (methodName.equals("ident") && (args == null || args.length == 0)) {
+ if ("ident".equals(methodName) && (args == null || args.length == 0)) {
return state.identifier();
}
- if ((methodName.equals("isDirty") || methodName.equals("hasChanged")) && (args == null || args.length == 0)) {
+ if (("isDirty".equals(methodName) || "hasChanged".equals(methodName)) && (args == null || args.length == 0)) {
return false;
}
- if (methodName.equals("toString") && (args == null || args.length == 0)) {
+ if ("toString".equals(methodName) && (args == null || args.length == 0)) {
return state.entityName() + ":" + state.identifier();
}
return INVOKE_IMPLEMENTATION;
}
public static boolean isGroovyMethod(String methodName) {
- return methodName.equals("getMetaClass") || methodName.equals("setMetaClass") ||
- methodName.equals("getProperty") || methodName.equals("setProperty") ||
- methodName.equals("invokeMethod");
+ return "getMetaClass".equals(methodName)
+ || "setMetaClass".equals(methodName)
+ || "getProperty".equals(methodName)
+ || "setProperty".equals(methodName)
+ || "invokeMethod".equals(methodName);
}
public static ProxyInstanceMetaClass getProxyInstanceMetaClass(Object o) {
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateAlias.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateAlias.java
index ece144f317..bd3fac0f6d 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateAlias.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HibernateAlias.java
@@ -22,23 +22,9 @@ import org.grails.datastore.mapping.query.Query;
/**
* A internal criterion used to represent an alias for a basic collection join.
- *
+ *
* @author walterduquedeestrada
*/
-public class HibernateAlias implements Query.Criterion, Query.QueryElement {
- private final String path;
- private final String alias;
-
- public HibernateAlias(String path, String alias) {
- this.path = path;
- this.alias = alias;
- }
-
- public String getPath() {
- return path;
- }
+public record HibernateAlias(String path, String alias) implements Query.Criterion, Query.QueryElement {
- public String getAlias() {
- return alias;
- }
}
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HqlQueryContext.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HqlQueryContext.java
index b1f6d72859..e50a5c35f7 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HqlQueryContext.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/HqlQueryContext.java
@@ -49,7 +49,7 @@ public record HqlQueryContext(
String hql,
Class<?> targetClass,
Map<String, Object> namedParams,
- Collection positionalParams,
+ Collection<?> positionalParams,
Map<String, Object> querySettings,
boolean isUpdate,
boolean isNative) {
@@ -65,13 +65,13 @@ public record HqlQueryContext(
PersistentEntity entity,
CharSequence queryCharseq,
Map<?, ?> namedParams,
- Collection positionalParams,
- Map querySettings,
+ Collection<?> positionalParams,
+ Map<String, Object> querySettings,
boolean isNative,
boolean isUpdate) {
Map<String, Object> _namedParams =
namedParams != null ? new HashMap<>((Map<String, Object>) namedParams) : new HashMap<>();
- Collection positionalParamsCopy = positionalParams != null ? new ArrayList<>(positionalParams) : null;
+ Collection<Object> positionalParamsCopy = positionalParams != null ? new ArrayList<>(positionalParams) : null;
Map<String, Object> querySettingsCopy = querySettings != null ? new HashMap<>(querySettings) : null;
String hql;
@@ -93,18 +93,18 @@ public record HqlQueryContext(
public static @Nullable String resolveHql(
CharSequence queryCharseq, boolean isNative, Map<String, Object> namedParams) {
- String raw = queryCharseq instanceof GString gstr ?
- buildNamedParameterQueryFromGString(gstr, namedParams) :
- queryCharseq != null ? queryCharseq.toString() : "";
+ String raw = queryCharseq instanceof GString gstr
+ ? buildNamedParameterQueryFromGString(gstr, namedParams)
+ : queryCharseq != null ? queryCharseq.toString() : "";
String normalized = normalizeMultiLineQueryString(raw);
return isNative ? normalized : normalizeNonAliasedSelect(normalized);
}
public static @Nullable String resolveHql(
- CharSequence queryCharseq, boolean isNative, Collection positionalParams) {
- String raw = queryCharseq instanceof GString gstr ?
- buildPositionalParameterQueryFromGString(gstr, positionalParams, isNative) :
- queryCharseq != null ? queryCharseq.toString() : "";
+ CharSequence queryCharseq, boolean isNative, Collection<Object> positionalParams) {
+ String raw = queryCharseq instanceof GString gstr
+ ? buildPositionalParameterQueryFromGString(gstr, positionalParams, isNative)
+ : queryCharseq != null ? queryCharseq.toString() : "";
String normalized = normalizeMultiLineQueryString(raw);
return isNative ? normalized : normalizeNonAliasedSelect(normalized);
}
@@ -133,7 +133,7 @@ public record HqlQueryContext(
* <p>Commas inside parentheses or string literals are ignored.
*/
static int countHqlProjections(CharSequence hql) {
- if (hql == null || hql.length() == 0) return 0;
+ if (hql == null || hql.isEmpty()) return 0;
String s = hql.toString().trim();
String lower = s.toLowerCase(Locale.ROOT);
int selectIdx = lower.indexOf("select ");
@@ -152,6 +152,11 @@ public record HqlQueryContext(
sel = sel.substring("all ".length()).trim();
// Count top-level commas, ignoring those inside parens or string literals
+ int commas = getCommas(sel);
+ return commas == 0 ? 1 : 2;
+ }
+
+ private static int getCommas(String sel) {
int depth = 0, commas = 0;
boolean inSingle = false, inDouble = false;
for (int i = 0; i < sel.length(); i++) {
@@ -170,7 +175,7 @@ public record HqlQueryContext(
else if (c == ',' && depth == 0) commas++;
}
}
- return commas == 0 ? 1 : 2;
+ return commas;
}
// ─── HQL normalization ────────────────────────────────────────────────────
@@ -217,8 +222,8 @@ public record HqlQueryContext(
int tokenEnd = cur;
while (tokenEnd < s.length() && !Character.isWhitespace(s.charAt(tokenEnd))) tokenEnd++;
String token = s.substring(cur, tokenEnd).toLowerCase(Locale.ROOT);
- boolean hasAlias = !token.isEmpty() &&
- !Set.of("where", "join", "left", "right", "inner", "outer", "group", "order", "having")
+ boolean hasAlias = !token.isEmpty()
+ && !Set.of("where", "join", "left", "right", "inner", "outer", "group", "order", "having")
.contains(token);
if (hasAlias) return s;
@@ -269,7 +274,6 @@ public record HqlQueryContext(
return query.trim().replace("\n", " ");
}
- @SuppressWarnings("unchecked")
private static String buildNamedParameterQueryFromGString(GString query, Map<String, Object> params) {
StringBuilder sql = new StringBuilder();
Object[] values = query.getValues();
@@ -285,9 +289,8 @@ public record HqlQueryContext(
return sql.toString();
}
- @SuppressWarnings("unchecked")
private static String buildPositionalParameterQueryFromGString(
- GString query, Collection positionalParams, boolean isNative) {
+ GString query, Collection<Object> positionalParams, boolean isNative) {
StringBuilder sql = new StringBuilder();
Object[] values = query.getValues();
String[] strings = query.getStrings();
@@ -299,7 +302,8 @@ public record HqlQueryContext(
} else {
sql.append('?').append(positionalParams.size() + 1);
}
- positionalParams.add(values[i]);
+ Object value = values[i];
+ positionalParams.add(value);
}
}
return sql.toString();
diff --git a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
index 3a23f6b1e8..7bc699eae9 100644
--- a/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
+++ b/grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/query/JpaFromProvider.java
@@ -95,7 +95,7 @@ public class JpaFromProvider implements Cloneable {
// Also scan for HibernateAlias (basic collections)
Map<String, String> basicAliasMap = new HashMap<>();
for (HibernateAlias ha : aliases) {
- basicAliasMap.put(ha.getPath(), ha.getAlias());
+ basicAliasMap.put(ha.path(), ha.alias());
}
var definedAliases = detachedAssociationCriteriaList.stream()
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateDatastoreSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateDatastoreSpec.groovy
index 6b320da48a..02b65e993a 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateDatastoreSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/HibernateDatastoreSpec.groovy
@@ -18,22 +18,79 @@
*/
package org.grails.orm.hibernate
+import grails.gorm.annotation.Entity
+import grails.gorm.specs.HibernateGormDatastoreSpec
import org.grails.orm.hibernate.cfg.Settings
-import spock.lang.Specification
+import org.hibernate.FlushMode
+import org.springframework.context.support.GenericApplicationContext
-/**
- * Created by graemerocher on 22/09/2016.
- */
-class HibernateDatastoreSpec extends Specification {
+class HibernateDatastoreSpec extends HibernateGormDatastoreSpec {
+
+ void "test basic properties"() {
+ expect:
+ datastore.sessionFactory != null
+ datastore.dataSource != null
+ datastore.transactionManager != null
+ datastore.mappingContext != null
+ datastore.applicationEventPublisher != null
+ datastore.dataSourceName == 'default'
+ }
+
+ void "test configuration settings"() {
+ expect:
+ !datastore.autoFlush // COMMIT mode in setupSpec
+ datastore.defaultFlushMode == FlushMode.COMMIT
+ !datastore.failOnError
+ datastore.cacheQueries
+ }
+
+ void "test getDatastoreForConnection"() {
+ expect:
+ datastore.getDatastoreForConnection('dataSource') == datastore
+ datastore.getDatastoreForConnection('default') == datastore
+ datastore.getDatastoreForConnection('DEFAULT') == datastore
+ }
+
+ void "test withFlushMode"() {
+ when:
+ boolean result = false
+ datastore.withFlushMode(FlushMode.ALWAYS) {
+ result = datastore.sessionFactory.currentSession.hibernateFlushMode == FlushMode.ALWAYS
+ return true
+ }
- void "test configure via map"() {
+ then:
+ result
+ datastore.sessionFactory.currentSession.hibernateFlushMode == FlushMode.COMMIT
+ }
+
+ void "test application context integration"() {
+ given:
+ def ctx = new GenericApplicationContext()
+ ctx.refresh()
+
+ when:
+ datastore.setApplicationContext(ctx)
+
+ then:
+ datastore.applicationContext == ctx
+ }
+
+ void "test configure via map (Legacy/Test constructor)"() {
when:"The map constructor is used"
def config = Collections.singletonMap(Settings.SETTING_DB_CREATE, "create-drop")
- HibernateDatastore datastore = new HibernateDatastore(config, Book)
+ HibernateDatastore testDatastore = new HibernateDatastore(config, GHUBook)
then:"GORM is configured correctly"
- Book.withNewSession {
- Book.count()
- } == 0
+ testDatastore.getMappingContext().getPersistentEntity(GHUBook.name) != null
+
+ cleanup:
+ testDatastore.close()
}
}
+
+@Entity
+class GHUBook {
+ Long id
+ String title
+}
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntitySpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntitySpec.groovy
index 3567ac20f8..7cd4236721 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntitySpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/GrailsHibernatePersistentEntitySpec.groovy
@@ -26,6 +26,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersi
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentProperty
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity
import org.grails.orm.hibernate.cfg.domainbinding.util.DefaultColumnNameFetcher
+import org.grails.datastore.mapping.core.connections.ConnectionSource
class GrailsHibernatePersistentEntitySpec extends HibernateGormDatastoreSpec {
@@ -155,7 +156,7 @@ class GrailsHibernatePersistentEntitySpec extends HibernateGormDatastoreSpec {
GrailsHibernatePersistentEntity vehicle = getPersistentEntity(Vehicle) as GrailsHibernatePersistentEntity
when:
- def children = vehicle.getChildEntities("DEFAULT")
+ def children = vehicle.getChildEntities(ConnectionSource.DEFAULT)
then:
children.size() == 2
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
index a102789dd1..0dbd3bc783 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/HibernateMappingContextSpec.groovy
@@ -30,6 +30,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsHibernatePersi
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.GrailsJpaMappingConfigurationStrategy
import org.grails.orm.hibernate.connections.HibernateConnectionSourceSettings
import org.springframework.validation.Errors
+import org.grails.datastore.mapping.core.connections.ConnectionSource
class HibernateMappingContextSpec extends HibernateGormDatastoreSpec {
@@ -120,11 +121,11 @@ class HibernateMappingContextSpec extends HibernateGormDatastoreSpec {
void "getHibernatePersistentEntities returns GrailsHibernatePersistentEntity instances"() {
when:
- def entities = mappingContext.getHibernatePersistentEntities("DEFAULT")
+ def entities = mappingContext.getHibernatePersistentEntities(ConnectionSource.DEFAULT)
then:
entities.every { it instanceof GrailsHibernatePersistentEntity }
- entities.every { it.dataSourceName == "DEFAULT" }
+ entities.every { it.dataSourceName == ConnectionSource.DEFAULT }
}
void "getHibernatePersistentEntities sets the dataSourceName on each entity"() {
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
index 10e34481b3..4ae93f37cb 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/RootBinderSpec.groovy
@@ -27,6 +27,7 @@ import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentE
import org.grails.orm.hibernate.cfg.domainbinding.util.MultiTenantFilterBinder
import org.hibernate.boot.spi.MetadataBuildingContext
import org.hibernate.mapping.RootClass
+import org.grails.datastore.mapping.core.connections.ConnectionSource
class RootBinderSpec extends HibernateGormDatastoreSpec {
@@ -53,7 +54,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
discriminatorPropertyBinder = Mock(DiscriminatorPropertyBinder)
binder = new RootBinder(
- "default",
+ ConnectionSource.DEFAULT,
multiTenantFilterBinder,
subClassBinder,
rootPersistentClassCommonValuesBinder,
@@ -67,7 +68,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
given:
def entity = Mock(HibernatePersistentEntity)
entity.getName() >> "Parent"
- entity.getChildEntities("default") >> []
+ entity.getChildEntities(ConnectionSource.DEFAULT) >> []
entity.getMappedForm() >> new Mapping()
def mappings = sharedCollector
@@ -91,7 +92,7 @@ class RootBinderSpec extends HibernateGormDatastoreSpec {
def entity = Mock(HibernatePersistentEntity)
def childEntity = Mock(HibernatePersistentEntity)
entity.getName() >> "Parent"
- entity.getChildEntities("default") >> [childEntity]
+ entity.getChildEntities(ConnectionSource.DEFAULT) >> [childEntity]
def mapping = new Mapping()
mapping.setTablePerHierarchy(true)
entity.getMappedForm() >> mapping
diff --git a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
index 3e0e0c69e6..30d3aacec2 100644
--- a/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
+++ b/grails-data-hibernate7/core/src/test/groovy/org/grails/orm/hibernate/cfg/domainbinding/binder/SubClassBinderSpec.groovy
@@ -22,12 +22,12 @@ package org.grails.orm.hibernate.cfg.domainbinding.binder
import org.hibernate.mapping.SingleTableSubclass
import grails.gorm.specs.HibernateGormDatastoreSpec
-import org.grails.orm.hibernate.cfg.Mapping
import org.grails.orm.hibernate.cfg.MappingCacheHolder
import org.grails.orm.hibernate.cfg.domainbinding.hibernate.HibernatePersistentEntity
import org.grails.orm.hibernate.cfg.domainbinding.util.MultiTenantFilterBinder
import org.hibernate.boot.spi.MetadataBuildingContext
import org.hibernate.mapping.RootClass
+import org.grails.datastore.mapping.core.connections.ConnectionSource
class SubClassBinderSpec extends HibernateGormDatastoreSpec {
@@ -48,7 +48,7 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
binder = new SubClassBinder(
subclassMappingBinder,
multiTenantFilterBinder,
- "default"
+ ConnectionSource.DEFAULT,
)
}
@@ -56,7 +56,7 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
given:
def subEntity = Mock(HibernatePersistentEntity)
subEntity.getName() >> "Child"
- subEntity.getChildEntities("default") >> []
+ subEntity.getChildEntities(ConnectionSource.DEFAULT) >> []
def rootClass = new RootClass(metadataBuildingContext)
rootClass.setEntityName("Parent")
rootClass.setJpaEntityName("Parent")
@@ -79,8 +79,8 @@ class SubClassBinderSpec extends HibernateGormDatastoreSpec {
def grandChildEntity = Mock(HibernatePersistentEntity)
subEntity.getName() >> "Child"
grandChildEntity.getName() >> "GrandChild"
- subEntity.getChildEntities("default") >> [grandChildEntity]
- grandChildEntity.getChildEntities("default") >> []
+ subEntity.getChildEntities(ConnectionSource.DEFAULT) >> [grandChildEntity]
+ grandChildEntity.getChildEntities(ConnectionSource.DEFAULT) >> []
def rootClass = new RootClass(metadataBuildingContext)
rootClass.setEntityName("Parent")
diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSource.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSource.java
index 8e1614f6cd..ac42ac79aa 100644
--- a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSource.java
+++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/core/connections/ConnectionSource.java
@@ -31,7 +31,14 @@ public interface ConnectionSource<T, S extends ConnectionSourceSettings> extends
/**
* The name of the default connection source
*/
- String DEFAULT = "DEFAULT";
+ String DEFAULT = "default";
+
+ /**
+ * The name of the default connection source used in previous versions of GORM
+ * @deprecated Use {@link #DEFAULT} instead
+ */
+ @Deprecated
+ String OLD_DEFAULT = "DEFAULT";
/**
* Constance for a mapping to all connection sources
diff --git a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/MappingContext.java b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/MappingContext.java
index d65f463061..9300985ec7 100644
--- a/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/MappingContext.java
+++ b/grails-datastore-core/src/main/groovy/org/grails/datastore/mapping/model/MappingContext.java
@@ -236,7 +236,7 @@ public interface MappingContext {
*/
void addMappingContextListener(Listener listener);
- PersistentEntity createEmbeddedEntity(Class type);
+ PersistentEntity createEmbeddedEntity(Class<?> type);
/**
* Obtains a {@link EntityReflector} instance for the given entity