From 228e3e4204a599d1ce76db0431615883475156d4 Mon Sep 17 00:00:00 2001 From: Falko Modler Date: Wed, 30 Jun 2021 13:18:30 +0200 Subject: [PATCH] spring-data-jpa: fix parse error on attribute from @Inheritance superclass --- .../spring/data/deployment/DotNames.java | 2 ++ .../data/deployment/MethodNameParser.java | 14 ++++---- .../it/spring/data/jpa/CatalogValue.java | 23 +++++++++++++ .../data/jpa/CatalogValueRepository.java | 8 +++++ .../spring/data/jpa/CatalogValueResource.java | 34 +++++++++++++++++++ .../data/jpa/FederalStateCatalogValue.java | 10 ++++++ .../FederalStateCatalogValueRepository.java | 9 +++++ .../src/main/resources/import.sql | 7 +++- .../data/jpa/CatalogValueResourceIT.java | 8 +++++ .../data/jpa/CatalogValueResourceTest.java | 28 +++++++++++++++ 10 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValue.java create mode 100644 integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueRepository.java create mode 100644 integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueResource.java create mode 100644 integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValue.java create mode 100644 integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValueRepository.java create mode 100644 integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceIT.java create mode 100644 integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceTest.java diff --git a/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/DotNames.java b/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/DotNames.java index 8566254fe2b0b..a009dfa8be31b 100644 --- a/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/DotNames.java +++ b/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/DotNames.java @@ -27,6 +27,7 @@ import javax.persistence.Entity; import javax.persistence.Id; +import javax.persistence.Inheritance; import javax.persistence.MappedSuperclass; import javax.persistence.Version; @@ -86,6 +87,7 @@ public final class DotNames { public static final DotName JPA_ID = DotName.createSimple(Id.class.getName()); public static final DotName VERSION = DotName.createSimple(Version.class.getName()); + public static final DotName JPA_INHERITANCE = DotName.createSimple(Inheritance.class.getName()); public static final DotName JPA_MAPPED_SUPERCLASS = DotName.createSimple(MappedSuperclass.class.getName()); public static final DotName JPA_ENTITY = DotName.createSimple(Entity.class.getName());; public static final DotName VOID = DotName.createSimple(void.class.getName()); diff --git a/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/MethodNameParser.java b/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/MethodNameParser.java index 9c275cdf77e4d..493213363e14b 100644 --- a/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/MethodNameParser.java +++ b/extensions/spring-data-jpa/deployment/src/main/java/io/quarkus/spring/data/deployment/MethodNameParser.java @@ -66,7 +66,7 @@ public class MethodNameParser { public MethodNameParser(ClassInfo entityClass, IndexView indexView) { this.entityClass = entityClass; this.indexView = indexView; - this.mappedSuperClassInfos = getMappedSuperClassInfos(indexView, entityClass); + this.mappedSuperClassInfos = getSuperClassInfos(indexView, entityClass); } public enum QueryType { @@ -508,13 +508,13 @@ private boolean entityContainsField(String fieldName) { } private FieldInfo getFieldInfo(String fieldName, ClassInfo entityClass, - MutableReference> mappedSuperClassInfos) { + MutableReference> superClassInfos) { FieldInfo fieldInfo = entityClass.field(fieldName); if (fieldInfo == null) { - if (mappedSuperClassInfos.isEmpty()) { - mappedSuperClassInfos.set(getMappedSuperClassInfos(indexView, entityClass)); + if (superClassInfos.isEmpty()) { + superClassInfos.set(getSuperClassInfos(indexView, entityClass)); } - for (ClassInfo superClass : mappedSuperClassInfos.get()) { + for (ClassInfo superClass : superClassInfos.get()) { fieldInfo = superClass.field(fieldName); if (fieldInfo != null) { break; @@ -524,13 +524,15 @@ private FieldInfo getFieldInfo(String fieldName, ClassInfo entityClass, return fieldInfo; } - private List getMappedSuperClassInfos(IndexView indexView, ClassInfo entityClass) { + private List getSuperClassInfos(IndexView indexView, ClassInfo entityClass) { List mappedSuperClassInfoElements = new ArrayList<>(3); Type superClassType = entityClass.superClassType(); while (superClassType != null && !superClassType.name().equals(DotNames.OBJECT)) { ClassInfo superClass = indexView.getClassByName(superClassType.name()); if (superClass.classAnnotation(DotNames.JPA_MAPPED_SUPERCLASS) != null) { mappedSuperClassInfoElements.add(superClass); + } else if (superClass.classAnnotation(DotNames.JPA_INHERITANCE) != null) { + mappedSuperClassInfoElements.add(superClass); } if (superClassType.kind() == Kind.CLASS) { diff --git a/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValue.java b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValue.java new file mode 100644 index 0000000000000..b813292c0494f --- /dev/null +++ b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValue.java @@ -0,0 +1,23 @@ +package io.quarkus.it.spring.data.jpa; + +import javax.persistence.DiscriminatorColumn; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; + +@Entity +@Inheritance(strategy = InheritanceType.SINGLE_TABLE) +@DiscriminatorColumn(name = "type") +public class CatalogValue extends AbstractEntity { + + private String key; + private String displayName; + + public String getKey() { + return key; + } + + public String getDisplayName() { + return displayName; + } +} diff --git a/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueRepository.java b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueRepository.java new file mode 100644 index 0000000000000..42f5dd35038d7 --- /dev/null +++ b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueRepository.java @@ -0,0 +1,8 @@ +package io.quarkus.it.spring.data.jpa; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CatalogValueRepository extends JpaRepository { + + CatalogValue findByKey(String key); +} diff --git a/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueResource.java b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueResource.java new file mode 100644 index 0000000000000..62ce3a13ccabd --- /dev/null +++ b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/CatalogValueResource.java @@ -0,0 +1,34 @@ +package io.quarkus.it.spring.data.jpa; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; + +@Path("/catalog-value") +public class CatalogValueResource { + + private final CatalogValueRepository repository; + + private final FederalStateCatalogValueRepository federalStateRepository; + + public CatalogValueResource(CatalogValueRepository repository, + FederalStateCatalogValueRepository federalStateRepository) { + this.repository = repository; + this.federalStateRepository = federalStateRepository; + } + + @Path("/super/{key}") + @GET + @Produces("application/json") + public CatalogValue findByKey(@PathParam("key") String key) { + return repository.findByKey(key); + } + + @Path("/federal-state/{key}") + @GET + @Produces("application/json") + public CatalogValue findFederalStateByKey(@PathParam("key") String key) { + return federalStateRepository.findByKey(key); + } +} diff --git a/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValue.java b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValue.java new file mode 100644 index 0000000000000..9eb2f69272d8c --- /dev/null +++ b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValue.java @@ -0,0 +1,10 @@ +package io.quarkus.it.spring.data.jpa; + +import javax.persistence.DiscriminatorValue; +import javax.persistence.Entity; + +@Entity +@DiscriminatorValue("federalState") +public class FederalStateCatalogValue extends CatalogValue { + +} diff --git a/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValueRepository.java b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValueRepository.java new file mode 100644 index 0000000000000..b960ddd6b0596 --- /dev/null +++ b/integration-tests/spring-data-jpa/src/main/java/io/quarkus/it/spring/data/jpa/FederalStateCatalogValueRepository.java @@ -0,0 +1,9 @@ +package io.quarkus.it.spring.data.jpa; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FederalStateCatalogValueRepository extends JpaRepository { + + // note: key is defined in superclass of FederalStateCatalogValue + FederalStateCatalogValue findByKey(String key); +} diff --git a/integration-tests/spring-data-jpa/src/main/resources/import.sql b/integration-tests/spring-data-jpa/src/main/resources/import.sql index 7f0a6e667e998..2efffe988d03f 100644 --- a/integration-tests/spring-data-jpa/src/main/resources/import.sql +++ b/integration-tests/spring-data-jpa/src/main/resources/import.sql @@ -80,4 +80,9 @@ INSERT INTO employee(id, user_id, first_name, last_name, team_id) VALUES (102, ' INSERT INTO MotorCar(id, brand, model) VALUES (1, 'Monteverdi', 'Hai 450'); INSERT INTO MotorCar(id, brand, model) VALUES (2, 'Rinspeed', 'iChange'); -INSERT INTO MotorCar(id, brand, model) VALUES (3, 'Rinspeed', 'Oasis'); \ No newline at end of file +INSERT INTO MotorCar(id, brand, model) VALUES (3, 'Rinspeed', 'Oasis'); + +INSERT INTO CatalogValue(id, key, displayName, type) VALUES (1, 'DE-BY', 'Bavaria', 'federalState'); +INSERT INTO CatalogValue(id, key, displayName, type) VALUES (2, 'DE-SN', 'Saxony', 'federalState'); +INSERT INTO CatalogValue(id, key, displayName, type) VALUES (3, 'DE', 'Germany', 'country'); +INSERT INTO CatalogValue(id, key, displayName, type) VALUES (4, 'FR', 'France', 'country'); \ No newline at end of file diff --git a/integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceIT.java b/integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceIT.java new file mode 100644 index 0000000000000..15d8a898404dd --- /dev/null +++ b/integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceIT.java @@ -0,0 +1,8 @@ +package io.quarkus.it.spring.data.jpa; + +import io.quarkus.test.junit.NativeImageTest; + +@NativeImageTest +public class CatalogValueResourceIT extends CatalogValueResourceTest { + +} diff --git a/integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceTest.java b/integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceTest.java new file mode 100644 index 0000000000000..bc4957bde68d0 --- /dev/null +++ b/integration-tests/spring-data-jpa/src/test/java/io/quarkus/it/spring/data/jpa/CatalogValueResourceTest.java @@ -0,0 +1,28 @@ +package io.quarkus.it.spring.data.jpa; + +import static io.restassured.RestAssured.when; +import static org.hamcrest.Matchers.containsString; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class CatalogValueResourceTest { + + @Test + void findByKey() { + when().get("/catalog-value/super/DE-SN").then() + .statusCode(200) + .body(containsString("Saxony")) + .body(containsString("DE-SN")); + } + + @Test + void findFederalStateByKey() { + when().get("/catalog-value/federal-state/DE-SN").then() + .statusCode(200) + .body(containsString("Saxony")) + .body(containsString("DE-SN")); + } +}