Currently, in AOT generation, types that are 2 or more layers of generics deep, such as
do not have accessors generated for them ahead of time.
On the other hand
has an accessor generated for it ahead of time,
From my testing, it seems that the output of line 127 of DefaultAotRepositoryContext is where the issues starts at - when V is nested two layers of generics deep, it isn't a part of the return value of this call; while if it's only one layer of generics deep, it is.
Due to the fact that no generator is being generated in the first case of V being two layers of generics deep, it causes the following exception to be thrown in runtime of the generated native image, when calling the repository associated to the entity class that references type V:
java.lang.IllegalStateException: org.springframework.cglib.core.CodeGenerationException:
com.oracle.svm.core.jdk.UnsupportedFeatureError
-->
Classes cannot be defined at runtime by default when using ahead-of-time Native Image compilation.
Concrete example:
@Repository
public interface EntityRepository extends MongoRepository<EntityClass, String> {
}
@Document("entities")
@Data
public class EntityClass {
@Id
private String id;
private Map<String, EntityChildOne> one;
private Map<String, Map<String, EntityChildTwo>> two;
}
EntityChildOne and EntityChildTwo are both simple POJOs with a single field.
Running the following:
mvn clean compile spring-boot:process-aot && find target/ -iname "*Entity*Accessor*"
Returns the following output, which only contains __Accessor(s) for EntityClass and EntityChildOne, regardless of the fact that EntityChildTwo is being referenced.
target/spring-aot/main/classes/com/example/spring_data_accessor_generation_issue/EntityChildOne__Accessor_1po17f.class
target/spring-aot/main/classes/com/example/spring_data_accessor_generation_issue/EntityClass__Accessor_r2t2jh.class
target/classes/com/example/spring_data_accessor_generation_issue/EntityChildOne__Accessor_1po17f.class
target/classes/com/example/spring_data_accessor_generation_issue/EntityClass__Accessor_r2t2jh.class
Considering that the runtime code tries to generate the EntityChildTwo accessor (which fails when running in a native context), is this something that could be fixed?
In case someone else has the same issue -> my current workaround is adding a final field with no getters/setters and annotating it with @Transient, which allows it to be picked up by the AOT processing but completely ignored otherwise.
Reproducing
Feel free to use this sample repository for reproducing the issue. Versions used:
- Java version: 25.0.4
spring-data-commons version: 4.0.7/4.1.1 (tested with both)
- GraalVM version: 25.2.4
Thanks in advance.
Currently, in AOT generation, types that are 2 or more layers of generics deep, such as
VinMap<K, Map<K, V>>do not have accessors generated for them ahead of time.
On the other hand
VinMap<K, V>has an accessor generated for it ahead of time,
From my testing, it seems that the output of line 127 of
DefaultAotRepositoryContextis where the issues starts at - whenVis nested two layers of generics deep, it isn't a part of the return value of this call; while if it's only one layer of generics deep, it is.Due to the fact that no generator is being generated in the first case of
Vbeing two layers of generics deep, it causes the following exception to be thrown in runtime of the generated native image, when calling the repository associated to the entity class that references typeV:Concrete example:
EntityChildOneandEntityChildTwoare both simple POJOs with a single field.Running the following:
Returns the following output, which only contains
__Accessor(s) forEntityClassandEntityChildOne, regardless of the fact thatEntityChildTwois being referenced.Considering that the runtime code tries to generate the
EntityChildTwoaccessor (which fails when running in a native context), is this something that could be fixed?In case someone else has the same issue -> my current workaround is adding a
finalfield with no getters/setters and annotating it with@Transient, which allows it to be picked up by the AOT processing but completely ignored otherwise.Reproducing
Feel free to use this sample repository for reproducing the issue. Versions used:
spring-data-commonsversion: 4.0.7/4.1.1 (tested with both)Thanks in advance.