Skip to content

Commit 47899ec

Browse files
Generic type reflection
Signed-off-by: Anders Swanson <anders.swanson@oracle.com>
1 parent 793fffa commit 47899ec

File tree

8 files changed

+50
-49
lines changed

8 files changed

+50
-49
lines changed

database/starters/oracle-spring-boot-json-relational-duality-views/src/main/java/com/oracle/spring/json/duality/annotation/JsonRelationalDualityView.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import java.lang.annotation.Target;
88

99
@Documented
10-
@Target({ElementType.TYPE})
10+
@Target({ElementType.TYPE, ElementType.FIELD})
1111
@Retention(RetentionPolicy.RUNTIME)
1212
public @interface JsonRelationalDualityView {
1313
String name() default "";

database/starters/oracle-spring-boot-json-relational-duality-views/src/main/java/com/oracle/spring/json/duality/annotation/JsonRelationalDualityViewEntity.java

Lines changed: 0 additions & 17 deletions
This file was deleted.

database/starters/oracle-spring-boot-json-relational-duality-views/src/main/java/com/oracle/spring/json/duality/builder/Annotations.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import com.oracle.spring.json.duality.annotation.AccessMode;
88
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityView;
9-
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityViewEntity;
109
import jakarta.json.bind.annotation.JsonbProperty;
1110
import jakarta.persistence.Column;
1211
import jakarta.persistence.JoinTable;
@@ -15,7 +14,6 @@
1514
import jakarta.persistence.OneToMany;
1615
import jakarta.persistence.OneToOne;
1716
import jakarta.persistence.Table;
18-
import org.hibernate.mapping.Join;
1917
import org.springframework.util.StringUtils;
2018

2119
public final class Annotations {
@@ -53,11 +51,11 @@ static JoinTable getJoinTableAnnotation( Field f, ManyToMany manyToMany, Class<?
5351
throw new IllegalArgumentException("No JoinTable found for field " + f.getName());
5452
}
5553

56-
static String getViewEntityName(Class<?> javaType,
57-
JsonRelationalDualityViewEntity viewEntityAnnotation,
58-
Table tableAnnotation) {
59-
if (viewEntityAnnotation != null && StringUtils.hasText(viewEntityAnnotation.name())) {
60-
return viewEntityAnnotation.name().toLowerCase();
54+
static String getNestedViewName(Class<?> javaType,
55+
JsonRelationalDualityView dvAnnotation,
56+
Table tableAnnotation) {
57+
if (dvAnnotation != null && StringUtils.hasText(dvAnnotation.name())) {
58+
return dvAnnotation.name().toLowerCase();
6159
}
6260
return getTableName(javaType, tableAnnotation).toLowerCase();
6361
}

database/starters/oracle-spring-boot-json-relational-duality-views/src/main/java/com/oracle/spring/json/duality/builder/ViewEntity.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.oracle.spring.json.duality.builder;
22

33
import java.lang.reflect.Field;
4+
import java.lang.reflect.ParameterizedType;
5+
import java.lang.reflect.Type;
46
import java.util.HashSet;
57
import java.util.Set;
68

7-
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityViewEntity;
9+
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityView;
810
import jakarta.json.bind.annotation.JsonbProperty;
911
import jakarta.persistence.Id;
1012
import jakarta.persistence.JoinColumn;
@@ -18,7 +20,7 @@
1820
import static com.oracle.spring.json.duality.builder.Annotations.getJoinTableAnnotation;
1921
import static com.oracle.spring.json.duality.builder.Annotations.getJsonbPropertyName;
2022
import static com.oracle.spring.json.duality.builder.Annotations.getTableName;
21-
import static com.oracle.spring.json.duality.builder.Annotations.getViewEntityName;
23+
import static com.oracle.spring.json.duality.builder.Annotations.getNestedViewName;
2224
import static com.oracle.spring.json.duality.builder.Annotations.isRelationalEntity;
2325

2426
final class ViewEntity {
@@ -94,12 +96,12 @@ private void parseField(Field f) {
9496
if (id != null && rootSnippet != null) {
9597
parseId(f);
9698
} else if (isRelationalEntity(f)) {
97-
JsonRelationalDualityViewEntity viewEntityAnnotation = f.getAnnotation(JsonRelationalDualityViewEntity.class);
99+
JsonRelationalDualityView dvAnnotation = f.getAnnotation(JsonRelationalDualityView.class);
98100
// The entity should not be included in the view.
99-
if (viewEntityAnnotation == null) {
101+
if (dvAnnotation == null) {
100102
return;
101103
}
102-
parseRelationalEntity(f, viewEntityAnnotation);
104+
parseRelationalEntity(f, dvAnnotation);
103105
} else {
104106
parseColumn(f);
105107
}
@@ -118,11 +120,11 @@ private void parseId(Field f) {
118120
addProperty(_ID_FIELD, getDatabaseColumnName(f));
119121
}
120122

121-
private void parseRelationalEntity(Field f, JsonRelationalDualityViewEntity viewEntityAnnotation) {
122-
Class<?> entityJavaType = viewEntityAnnotation.entity();
123+
private void parseRelationalEntity(Field f, JsonRelationalDualityView dvAnnotation) {
124+
Class<?> entityJavaType = getGenericFieldType(f);
123125
if (entityJavaType == null) {
124126
throw new IllegalArgumentException("%s %s annotation must include the entity class".formatted(
125-
f.getName(), JsonRelationalDualityViewEntity.class.getSimpleName()
127+
f.getName(), JsonRelationalDualityView.class.getSimpleName()
126128
));
127129
}
128130

@@ -136,17 +138,29 @@ private void parseRelationalEntity(Field f, JsonRelationalDualityViewEntity view
136138
parseManyToMany(manyToMany, f, entityJavaType);
137139
}
138140
// Add nested entity.
139-
parseNestedEntity(entityJavaType, viewEntityAnnotation);
141+
parseNestedEntity(entityJavaType, dvAnnotation);
140142
// Additional trailer for join table if present.
141143
if (manyToMany != null) {
142144
addTrailer(true);
143145
}
144146
}
145147

146-
private void parseNestedEntity(Class<?> entityJavaType, JsonRelationalDualityViewEntity viewEntityAnnotation) {
148+
private Class<?> getGenericFieldType(Field f) {
149+
Type genericType = f.getGenericType();
150+
if (genericType instanceof ParameterizedType p) {
151+
Type type = p.getActualTypeArguments()[0];
152+
if (type instanceof Class<?> c) {
153+
return c;
154+
}
155+
throw new IllegalStateException("failed to process type: " + type);
156+
}
157+
return f.getType();
158+
}
159+
160+
private void parseNestedEntity(Class<?> entityJavaType, JsonRelationalDualityView dvAnnotation) {
147161
Table tableAnnotation = entityJavaType.getAnnotation(Table.class);
148-
String viewEntityName = getViewEntityName(entityJavaType, viewEntityAnnotation, tableAnnotation);
149-
String accessMode = getAccessModeStr(viewEntityAnnotation.accessMode());
162+
String viewEntityName = getNestedViewName(entityJavaType, dvAnnotation, tableAnnotation);
163+
String accessMode = getAccessModeStr(dvAnnotation.accessMode());
150164
ViewEntity ve = new ViewEntity(entityJavaType,
151165
new StringBuilder(),
152166
accessMode,

database/starters/oracle-spring-boot-json-relational-duality-views/src/test/java/com/oracle/spring/json/duality/builder/DualityViewBuilderTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.oracle.spring.json.duality.builder;
22

3+
import java.lang.reflect.Field;
4+
import java.util.ArrayList;
35
import java.util.stream.Stream;
46

57
import com.oracle.spring.json.duality.model.movie.Actor;
8+
import com.oracle.spring.json.duality.model.movie.Movie;
69
import com.oracle.spring.json.duality.model.student.Student;
710
import org.jetbrains.annotations.NotNull;
11+
import org.junit.jupiter.api.Test;
812
import org.junit.jupiter.params.ParameterizedTest;
913
import org.junit.jupiter.params.provider.Arguments;
1014
import org.junit.jupiter.params.provider.MethodSource;
@@ -42,4 +46,11 @@ private DualityViewBuilder getDualityViewBuilder(String ddlAuto) {
4246
hibernateProperties
4347
);
4448
}
49+
50+
@Test
51+
void t() throws Exception {
52+
Field m = Actor.class.getDeclaredField("movies");
53+
54+
System.out.println(m.getGenericType());
55+
}
4556
}

database/starters/oracle-spring-boot-json-relational-duality-views/src/test/java/com/oracle/spring/json/duality/model/movie/Actor.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.util.Set;
66

77
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityView;
8-
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityViewEntity;
98
import jakarta.json.bind.annotation.JsonbProperty;
109
import jakarta.persistence.Column;
1110
import jakarta.persistence.Entity;
@@ -38,9 +37,7 @@ public class Actor {
3837
private String lastName;
3938

4039
@ManyToMany(mappedBy = "actors")
41-
@JsonRelationalDualityViewEntity(
42-
entity = Movie.class
43-
)
40+
@JsonRelationalDualityView
4441
private Set<Movie> movies;
4542

4643
/**

database/starters/oracle-spring-boot-json-relational-duality-views/src/test/java/com/oracle/spring/json/duality/model/movie/Director.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import java.util.Objects;
44
import java.util.Set;
55

6-
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityViewEntity;
6+
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityView;
77
import jakarta.persistence.CascadeType;
88
import jakarta.persistence.Column;
99
import jakarta.persistence.Entity;
@@ -33,7 +33,7 @@ public class Director {
3333
@Column(name = "last_name", nullable = false, length = 50)
3434
private String lastName;
3535

36-
@JsonRelationalDualityViewEntity(entity = Movie.class)
36+
@JsonRelationalDualityView
3737
@OneToMany(mappedBy = "director") // Reference related entity's associated field
3838
private Set<Movie> movies;
3939

@@ -44,7 +44,7 @@ public class Director {
4444
)
4545
// The primary key of the Director entity is used as the foreign key of the DirectorBio entity.
4646
@PrimaryKeyJoinColumn
47-
@JsonRelationalDualityViewEntity(entity = DirectorBio.class)
47+
@JsonRelationalDualityView
4848
private DirectorBio directorBio;
4949

5050
public void setDirectorBio(DirectorBio directorBio) {

database/starters/oracle-spring-boot-json-relational-duality-views/src/test/java/com/oracle/spring/json/duality/model/movie/Movie.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import java.util.Objects;
44
import java.util.Set;
55

6-
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityViewEntity;
6+
import com.oracle.spring.json.duality.annotation.JsonRelationalDualityView;
77
import jakarta.persistence.Column;
88
import jakarta.persistence.Entity;
99
import jakarta.persistence.GeneratedValue;
@@ -38,13 +38,11 @@ public class Movie {
3838

3939
@ManyToOne
4040
@JoinColumn(name = "director_id")
41-
@JsonRelationalDualityViewEntity(entity = Director.class)
41+
@JsonRelationalDualityView
4242
private Director director;
4343

4444
@ManyToMany
45-
@JsonRelationalDualityViewEntity(
46-
entity = Actor.class
47-
)
45+
@JsonRelationalDualityView
4846
@JoinTable(
4947
name = "movie_actor",
5048
joinColumns = @JoinColumn(name = "movie_id"),

0 commit comments

Comments
 (0)