jamesfredley commented on code in PR #16695:
URL: https://github.com/apache/grails-core/pull/16695#discussion_r4339129900
##########
grails-data-hibernate7/core/src/main/groovy/org/grails/orm/hibernate/cfg/domainbinding/hibernate/HibernatePersistentProperty.java:
##########
@@ -114,23 +123,43 @@ default GrailsHibernatePersistentEntity
getHibernateOwner() {
return (GrailsHibernatePersistentEntity) getOwner();
}
- @SuppressWarnings("PMD.DataflowAnomalyAnalysis")
default Class<?> getUserType() {
PropertyConfig config = getMappedForm();
if (config == null) return null;
Object typeObj = config.getType();
- Class<?> userType = null;
- if (typeObj instanceof Class<?>) {
- userType = (Class<?>) typeObj;
- } else if (typeObj != null) {
- String typeName = typeObj.toString();
- try {
- userType = Class.forName(typeName, true,
Thread.currentThread().getContextClassLoader());
- } catch (ClassNotFoundException ignored) {
- // ignore
- }
+ if (typeObj instanceof Class<?> userType) {
+ return userType;
+ }
+ return typeObj == null ? null : classForName(typeObj.toString());
+ }
+
+ /**
+ * The {@link CompositeUserType} the property is mapped with: the {@code
type} of its own mapping, or
+ * the {@code user-type} registered for its class in the mapping of its
owner, when that class
+ * implements the interface. A composite user type spans one column per
attribute of its
+ * {@linkplain CompositeUserType#embeddable() embeddable class} and is
bound as a component.
+ *
+ * @return The composite user type, or {@code null} when the property is
not mapped with one
+ */
+ @SuppressWarnings("unchecked")
+ default @Nullable Class<? extends CompositeUserType<?>>
getCompositeUserType() {
+ Class<?> userType = getUserType();
+ if (userType == null) {
+ userType = getRegisteredUserType();
Review Comment:
This fallback runs whenever `getUserType()` returns null, and
`getUserType()` returns null for a Hibernate alias such as `serializable`
because that string is not a class name. A value class that has a registered
composite user type, with an explicit `amount type: 'serializable'`, is
therefore bound as a multi-column component instead of one serialized column.
That changes the schema and can break an existing database. It also contradicts
the documented per-property precedence.
Consult the registered type only when the property mapping has no explicit
`type`. Please add a datastore-backed regression: a global composite
registration plus a per-property `serializable` override, asserting one basic
column and a successful round-trip.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]