diff --git a/src/main/java/org/apache/ibatis/reflection/Reflector.java b/src/main/java/org/apache/ibatis/reflection/Reflector.java index 35f1a93c14f..515cace7941 100644 --- a/src/main/java/org/apache/ibatis/reflection/Reflector.java +++ b/src/main/java/org/apache/ibatis/reflection/Reflector.java @@ -76,10 +76,10 @@ public Reflector(Type type) { this.clazz = (Class) type; } addDefaultConstructor(clazz); - Method[] classMethods = getClassMethods(clazz); if (isRecord(clazz)) { - addRecordGetMethods(classMethods); + addRecordGetMethods(clazz); } else { + Method[] classMethods = getClassMethods(clazz); addGetMethods(classMethods); addSetMethods(classMethods); addFields(clazz); @@ -94,9 +94,18 @@ public Reflector(Type type) { } } - private void addRecordGetMethods(Method[] methods) { - Arrays.stream(methods).filter(m -> m.getParameterTypes().length == 0) - .forEach(m -> addGetMethod(m.getName(), m, false)); + private void addRecordGetMethods(Class recordClass) { + Arrays.stream(recordClass.getDeclaredFields()).filter(field -> !Modifier.isStatic(field.getModifiers())) + .forEach(field -> { + try { + String fieldName = field.getName(); + // record's get method and field have the same name + Method m = recordClass.getMethod(fieldName); + addGetMethod(fieldName, m, false); + } catch (NoSuchMethodException ignore) { + // A standard record can never throw this exception + } + }); } private void addDefaultConstructor(Class clazz) { diff --git a/src/test/java/org/apache/ibatis/reflection/ReflectorTest.java b/src/test/java/org/apache/ibatis/reflection/ReflectorTest.java index 1b09ba18c1e..63c94e551c6 100644 --- a/src/test/java/org/apache/ibatis/reflection/ReflectorTest.java +++ b/src/test/java/org/apache/ibatis/reflection/ReflectorTest.java @@ -406,4 +406,20 @@ public Foo getFoo() { assertEquals(Foo.class, setter.getRawType()); assertArrayEquals(new Type[] { String.class }, setter.getActualTypeArguments()); } + + @Test + void shouldReflectRecord() throws Exception { + record User(Long id, String name, List props) { + @SuppressWarnings("unused") + public int foo() { + return 1; + } + } + + ReflectorFactory reflectorFactory = new DefaultReflectorFactory(); + Reflector reflector = reflectorFactory.findForClass(User.class); + List property = Arrays.asList(reflector.getGetablePropertyNames()); + assertEquals(3, property.size()); + assertTrue(property.containsAll(Arrays.asList("id", "name", "props"))); + } }