diff --git a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2EnumsMappingSpec.groovy b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2EnumsMappingSpec.groovy index 2f12ad3e32..6b6732a5a1 100644 --- a/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2EnumsMappingSpec.groovy +++ b/data-jdbc/src/test/groovy/io/micronaut/data/jdbc/h2/H2EnumsMappingSpec.groovy @@ -1,6 +1,7 @@ package io.micronaut.data.jdbc.h2 import io.micronaut.context.ApplicationContext +import io.micronaut.core.annotation.Introspected import io.micronaut.data.annotation.GeneratedValue import io.micronaut.data.annotation.Id import io.micronaut.data.annotation.MappedEntity @@ -14,12 +15,11 @@ import io.micronaut.data.model.query.builder.sql.Dialect import io.micronaut.data.model.query.builder.sql.SqlQueryBuilder import io.micronaut.data.repository.CrudRepository import io.micronaut.test.extensions.spock.annotation.MicronautTest +import jakarta.inject.Inject import spock.lang.AutoCleanup -import spock.lang.PendingFeature import spock.lang.Shared import spock.lang.Specification -import jakarta.inject.Inject import javax.persistence.Entity import javax.persistence.EnumType import javax.persistence.Enumerated @@ -46,7 +46,7 @@ class H2EnumsMappingSpec extends Specification implements H2TestPropertyProvider void 'test read lower case enum'() { when: - enumEntityRepository.insertValueExplicit("b", "B") + enumEntityRepository.insertValueExplicit("B", "b") def result = enumEntityRepository.findByAsString(MyEnum.B) then: @@ -68,6 +68,12 @@ class H2EnumsMappingSpec extends Specification implements H2TestPropertyProvider entity.asDefault == MyEnum.A entity.asString == MyEnum.B entity.asInt == MyEnum.C + when: + def dto = enumEntityRepository.queryById(entity.id) + then: + dto.asDefault == "a" + dto.asString == "b" + dto.asInt == 2 when: int updated = enumEntityRepository.update(entity.id, MyEnum.D, MyEnum.E, MyEnum.F) entity = enumEntityRepository.findById(entity.id).get() @@ -159,6 +165,8 @@ abstract class EnumEntityRepository implements CrudRepository abstract Optional find(MyEnum asDefault, MyEnum asString, MyEnum asInt) + abstract EnumEntityDto queryById(Long id) + } @JdbcRepository(dialect = Dialect.H2) @@ -183,6 +191,14 @@ class EnumEntity { MyEnum asInt } +@Introspected +class EnumEntityDto { + + String asDefault + String asString + Object asInt +} + @Entity class JpaEnumEntity { @javax.persistence.Id @@ -197,4 +213,9 @@ class JpaEnumEntity { enum MyEnum { A, B, C, D, E, F + + @Override + String toString() { + return name().toLowerCase(); + } } \ No newline at end of file diff --git a/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/QueryCriteriaMethodMatch.java b/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/QueryCriteriaMethodMatch.java index 6c273eb102..bdcfea271c 100644 --- a/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/QueryCriteriaMethodMatch.java +++ b/data-processor/src/main/java/io/micronaut/data/processor/visitors/finders/criteria/QueryCriteriaMethodMatch.java @@ -271,14 +271,14 @@ private boolean isDtoType(ClassElement classElement) { private List getDtoProjectionProperties(SourcePersistentEntity entity, ClassElement returnType) { return returnType.getBeanProperties().stream() - .filter(beanProperty -> { - String propertyName = beanProperty.getName(); + .filter(dtoProperty -> { + String propertyName = dtoProperty.getName(); // ignore Groovy meta class - return !"metaClass".equals(propertyName) || !beanProperty.getType().isAssignable("groovy.lang.MetaClass"); + return !"metaClass".equals(propertyName) || !dtoProperty.getType().isAssignable("groovy.lang.MetaClass"); }) - .map(beanProperty -> { - String propertyName = beanProperty.getName(); - if ("metaClass".equals(propertyName) && beanProperty.getType().isAssignable("groovy.lang.MetaClass")) { + .map(dtoProperty -> { + String propertyName = dtoProperty.getName(); + if ("metaClass".equals(propertyName) && dtoProperty.getType().isAssignable("groovy.lang.MetaClass")) { // ignore Groovy meta class return null; } @@ -292,8 +292,13 @@ private List getDtoProjectionProperties(SourcePersiste throw new MatchFailedException("Property " + propertyName + " is not present in entity: " + entity.getName()); } - if (!TypeUtils.areTypesCompatible(beanProperty.getType(), pp.getType())) { - throw new MatchFailedException("Property [" + propertyName + "] of type [" + beanProperty.getType().getName() + "] is not compatible with equivalent property declared in entity: " + entity.getName()); + ClassElement dtoPropertyType = dtoProperty.getType(); + if (dtoPropertyType.getName().equals("java.lang.Object") || dtoPropertyType.getName().equals("java.lang.String")) { + // Convert anything to a string or an object + return pp; + } + if (!TypeUtils.areTypesCompatible(dtoPropertyType, pp.getType())) { + throw new MatchFailedException("Property [" + propertyName + "] of type [" + dtoPropertyType.getName() + "] is not compatible with equivalent property of type [" + pp.getType().getName() + "] declared in entity: " + entity.getName()); } return pp; }).collect(Collectors.toList()); diff --git a/data-processor/src/test/groovy/io/micronaut/data/processor/visitors/DtoSpec.groovy b/data-processor/src/test/groovy/io/micronaut/data/processor/visitors/DtoSpec.groovy index 78dd6c20e9..55008ae2a8 100644 --- a/data-processor/src/test/groovy/io/micronaut/data/processor/visitors/DtoSpec.groovy +++ b/data-processor/src/test/groovy/io/micronaut/data/processor/visitors/DtoSpec.groovy @@ -119,7 +119,7 @@ class PersonDto { """) then: def e = thrown(RuntimeException) - e.message.contains('Property [name] of type [int] is not compatible with equivalent property declared in entity: io.micronaut.data.model.entities.Person') + e.message.contains('Property [name] of type [int] is not compatible with equivalent property of type [java.lang.String] declared in entity: io.micronaut.data.model.entities.Person') } diff --git a/data-runtime/src/main/java/io/micronaut/data/runtime/mapper/QueryStatement.java b/data-runtime/src/main/java/io/micronaut/data/runtime/mapper/QueryStatement.java index 5dd8d5e35f..bca6afa693 100644 --- a/data-runtime/src/main/java/io/micronaut/data/runtime/mapper/QueryStatement.java +++ b/data-runtime/src/main/java/io/micronaut/data/runtime/mapper/QueryStatement.java @@ -68,7 +68,7 @@ default QueryStatement setDynamic( if (value instanceof CharSequence) { str = value.toString(); } else if (value instanceof Enum) { - str = ((Enum) value).name(); + str = value.toString(); } else { str = convertRequired(value, String.class); }