Filter delegated properties for Kotlin data classes.
We now filter delegated properties (such as lazy) from being managed as persistent properties. Closes #3112
This commit is contained in:
@@ -314,7 +314,7 @@ Consider the following `data` class `Person`:
|
||||
data class Person(val id: String, val name: String)
|
||||
----
|
||||
|
||||
The class above compiles to a typical class with an explicit constructor.We can customize this class by adding another constructor and annotate it with `@PersistenceCreator` to indicate a constructor preference:
|
||||
The class above compiles to a typical class with an explicit constructor. We can customize this class by adding another constructor and annotate it with `@PersistenceCreator` to indicate a constructor preference:
|
||||
|
||||
[source,kotlin]
|
||||
----
|
||||
@@ -335,6 +335,9 @@ data class Person(var id: String, val name: String = "unknown")
|
||||
|
||||
Every time the `name` parameter is either not part of the result or its value is `null`, then the `name` defaults to `unknown`.
|
||||
|
||||
NOTE: Delegated properties are not supported with Spring Data. The mapping metadata filters delegated properties for Kotlin Data classes.
|
||||
In all other cases you can exclude synthetic fields for delegated properties by annotating the property with `@delegate:org.springframework.data.annotation.Transient`.
|
||||
|
||||
[[property-population-of-kotlin-data-classes]]
|
||||
=== Property population of Kotlin data classes
|
||||
|
||||
|
||||
@@ -770,6 +770,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
matches.add(new PropertyMatch("class", null));
|
||||
matches.add(new PropertyMatch("this\\$.*", null));
|
||||
matches.add(new PropertyMatch("metaClass", "groovy.lang.MetaClass"));
|
||||
matches.add(new KotlinDataClassPropertyMatch(".*\\$delegate", null));
|
||||
|
||||
UNMAPPED_PROPERTIES = Streamable.of(matches);
|
||||
}
|
||||
@@ -782,7 +783,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
}
|
||||
|
||||
return UNMAPPED_PROPERTIES.stream()//
|
||||
.noneMatch(it -> it.matches(field.getName(), field.getType()));
|
||||
.noneMatch(it -> it.matches(field));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -800,7 +801,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
}
|
||||
|
||||
return UNMAPPED_PROPERTIES.stream()//
|
||||
.noneMatch(it -> it.matches(property.getName(), property.getType()));
|
||||
.noneMatch(it -> it.matches(property));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -832,6 +833,26 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
/**
|
||||
* Returns whether the given {@link Field} matches the defined {@link PropertyMatch}.
|
||||
*
|
||||
* @param field must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public boolean matches(Field field) {
|
||||
return matches(field.getName(), field.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link Property} matches the defined {@link PropertyMatch}.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
public boolean matches(Property property) {
|
||||
return matches(property.getName(), property.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given field name and type matches the defined {@link PropertyMatch}.
|
||||
*
|
||||
* @param name must not be {@literal null}.
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
@@ -852,6 +873,41 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Value object extension to {@link PropertyMatch} that matches for fields only for Kotlin data classes.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 3.3.2
|
||||
*/
|
||||
static class KotlinDataClassPropertyMatch extends PropertyMatch {
|
||||
|
||||
public KotlinDataClassPropertyMatch(@Nullable String namePattern, @Nullable String typeName) {
|
||||
super(namePattern, typeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Field field) {
|
||||
|
||||
if (!KotlinReflectionUtils.isDataClass(field.getDeclaringClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.matches(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Property property) {
|
||||
|
||||
Field field = property.getField().orElse(null);
|
||||
|
||||
if (field == null || !KotlinReflectionUtils.isDataClass(field.getDeclaringClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return super.matches(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user