Skip to content

Commit ea69462

Browse files
committed
noticket: Move EntitySchema ID field validation to after the entity's JavaFields have been properly reflected
1 parent 112a6d7 commit ea69462

File tree

3 files changed

+45
-18
lines changed

3 files changed

+45
-18
lines changed

repository/src/main/java/tech/ydb/yoj/repository/db/EntityIdSchema.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public static <T extends Entity<T>, ID extends Entity.Id<T>> EntityIdSchema<ID>
144144
return entitySchema.getRegistry().getOrCreate(EntityIdSchema.class, (k, r) -> new EntityIdSchema<>(entitySchema), key);
145145
}
146146

147-
static Class<?> resolveEntityType(Class<?> idType) {
147+
static Class<?> resolveEntityType(Type idType) {
148148
return TypeToken.of(idType).resolveType(ENTITY_TYPE_PARAMETER).getRawType();
149149
}
150150

repository/src/main/java/tech/ydb/yoj/repository/db/EntitySchema.java

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public static <T extends Entity<T>> EntitySchema<T> of(SchemaRegistry registry,
4747

4848
private EntitySchema(SchemaKey<T> key, Reflector reflector, SchemaRegistry registry) {
4949
super(checkEntityType(key), reflector);
50+
checkIdField();
51+
5052
this.registry = registry;
5153
}
5254

@@ -55,38 +57,40 @@ private static <T extends Entity<T>> SchemaKey<T> checkEntityType(SchemaKey<T> k
5557

5658
if (!Entity.class.isAssignableFrom(entityType)) {
5759
throw new IllegalArgumentException(format(
58-
"Entity type [%s] must implement [%s]", entityType.getName(), Entity.class));
60+
"Entity type [%s] must implement [%s]", entityType.getName(), Entity.class.getName()
61+
));
5962
}
6063

6164
Class<?> entityTypeFromEntityIface = resolveEntityTypeFromEntityIface(entityType);
6265
if (!entityTypeFromEntityIface.equals(entityType)) {
6366
throw new IllegalArgumentException(format(
6467
"Entity type [%s] must implement [%s] specified by the same type, but it is specified by [%s]",
65-
entityType.getName(), Entity.class, entityTypeFromEntityIface.getName()));
68+
entityType.getName(), Entity.class.getName(), entityTypeFromEntityIface.getName()
69+
));
6670
}
6771

68-
Class<?> idFieldType;
69-
try {
70-
idFieldType = entityType.getDeclaredField(EntityIdSchema.ID_FIELD_NAME).getType();
71-
} catch (NoSuchFieldException e) {
72-
throw new IllegalArgumentException(format(
73-
"Entity type [%s] does not contain a mandatory \"%s\" field",
74-
entityType.getName(), EntityIdSchema.ID_FIELD_NAME));
75-
}
72+
return key;
73+
}
74+
75+
private void checkIdField() {
76+
JavaField idField = findField(EntityIdSchema.ID_FIELD_NAME)
77+
.orElseThrow(() -> new IllegalArgumentException(format(
78+
"Entity type [%s] does not contain a mandatory \"%s\" field",
79+
getType().getName(), EntityIdSchema.ID_FIELD_NAME
80+
)));
7681

77-
if (!Entity.Id.class.isAssignableFrom(idFieldType)) {
82+
if (!Entity.Id.class.isAssignableFrom(idField.getRawType())) {
7883
throw new IllegalArgumentException(format(
79-
"Entity ID type [%s] must implement [%s]", idFieldType.getName(), Entity.Id.class));
84+
"Entity ID type [%s] must implement %s", idField.getType().getTypeName(), Entity.Id.class.getName()
85+
));
8086
}
8187

82-
Class<?> entityTypeFromIdType = EntityIdSchema.resolveEntityType(idFieldType);
83-
if (!entityTypeFromIdType.equals(entityType)) {
88+
Class<?> entityTypeFromIdType = EntityIdSchema.resolveEntityType(idField.getType());
89+
if (!entityTypeFromIdType.equals(getType())) {
8490
throw new IllegalArgumentException(format(
8591
"An identifier field \"%s\" has a type [%s] that is not an identifier type for an entity of type [%s]",
86-
EntityIdSchema.ID_FIELD_NAME, idFieldType.getName(), entityType.getName()));
92+
EntityIdSchema.ID_FIELD_NAME, idField.getType().getTypeName(), getType().getTypeName()));
8793
}
88-
89-
return key;
9094
}
9195

9296
static Class<?> resolveEntityTypeFromEntityIface(Class<?> entityType) {

repository/src/test/java/tech/ydb/yoj/repository/db/PojoEntitySchemaTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public void testEntitySchemaEntityNotId() {
4343
@Test
4444
public void testEntitySchemaEntityIncorrectIdType() {
4545
assertThatIllegalArgumentException().isThrownBy(() -> EntitySchema.of(EntityIncorrectIdType.class));
46+
assertThatIllegalArgumentException().isThrownBy(() -> EntitySchema.of(EntityIncorrectIdExplicitGeneric.class));
47+
assertThatIllegalArgumentException().isThrownBy(() -> EntitySchema.of(EntityIncorrectRawTypeEntityId.class));
4648
}
4749

4850
@Test(expected = IllegalArgumentException.class)
@@ -97,6 +99,27 @@ public Id<EntityIncorrectIdType> getId() {
9799
}
98100
}
99101

102+
@Value
103+
static class EntityIncorrectIdExplicitGeneric implements Entity<EntityIncorrectIdExplicitGeneric> {
104+
Entity.Id<CorrectEntity> id;
105+
106+
@Override
107+
public Id<EntityIncorrectIdExplicitGeneric> getId() {
108+
return null;
109+
}
110+
}
111+
112+
@Value
113+
static class EntityIncorrectRawTypeEntityId implements Entity<EntityIncorrectRawTypeEntityId> {
114+
@SuppressWarnings("rawtypes")
115+
Entity.Id id;
116+
117+
@Override
118+
public Id<EntityIncorrectRawTypeEntityId> getId() {
119+
return null;
120+
}
121+
}
122+
100123
@Value
101124
private static final class ColumnNameClashes implements Entity<ColumnNameClashes> {
102125
@Column

0 commit comments

Comments
 (0)