映射处理器中的内部错误:java.lang.StackOverflowError

时间:2016-11-26 18:01:41

标签: java mapstruct

在尝试映射我的域对象时,我得到以下StackOverflowError异常。我试图忽略导致循环依赖的属性无济于事。

我的域模型的核心是WorkoutSet,它有一个User和一个练习。

如果从WorkoutSetMapper中删除映射注释,则会按预期生成UserMapperImpl和ExerciseMapperImpl。

  

错误:(15,1)java:映射处理器中的内部错误:   java.lang.StackOverflowError at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ UnaryVisitor.visit(Types.java:4652)     在com.sun.tools.javac.code.Types.supertype(Types.java:2315)at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1966)at at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1955)at at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ DefaultTypeVisitor.visit(Types.java:4571)     在com.sun.tools.javac.code.Types.asSuper(Types.java:1952)at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1968)at at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1955)at at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ DefaultTypeVisitor.visit(Types.java:4571)     在com.sun.tools.javac.code.Types.asSuper(Types.java:1952)at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1975)at at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1955)at at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ DefaultTypeVisitor.visit(Types.java:4571)     在com.sun.tools.javac.code.Types.asSuper(Types.java:1952)at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1975)at at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1955)at at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ DefaultTypeVisitor.visit(Types.java:4571)     在com.sun.tools.javac.code.Types.asSuper(Types.java:1952)at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1975)at at   com.sun.tools.javac.code.Types $ 13.visitClassType(Types.java:1955)at at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ DefaultTypeVisitor.visit(Types.java:4571)     在com.sun.tools.javac.code.Types.asSuper(Types.java:1952)at   com.sun.tools.javac.code.Types $ 4.visitClassType(Types.java:921)at at   com.sun.tools.javac.code.Types $ 4.visitClassType(Types.java:844)at at   com.sun.tools.javac.code.Type $ ClassType.accept(Type.java:786)at at   com.sun.tools.javac.code.Types $ DefaultTypeVisitor.visit(Types.java:4571)     在com.sun.tools.javac.code.Types.isSubtype(Types.java:840)at   com.sun.tools.javac.code.Types.isSubtype(Types.java:804)at   com.sun.tools.javac.model.JavacTypes.isSubtype(JavacTypes.java:98)     在   org.mapstruct.ap.internal.util.workarounds.SpecificCompilerWorkarounds.isSubtype(SpecificCompilerWorkarounds.java:76)     在   org.mapstruct.ap.internal.util.workarounds.TypesDecorator.isSubtype(TypesDecorator.java:68)     在   org.mapstruct.ap.internal.model.common.Type.isSubType(Type.java:638)     在   org.mapstruct.ap.internal.model.common.Type.isCollection(Type.java:628)     在   org.mapstruct.ap.internal.model.common.Type.isCollectionOrMap(Type.java:624)     在   org.mapstruct.ap.internal.model.common.Type.getAlternativeTargetAccessors(Type.java:598)     在   org.mapstruct.ap.internal.model.common.Type.getPropertyWriteAccessors(Type.java:419)     在   org.mapstruct.ap.internal.model.source.TargetReference $ BuilderFromTargetMapping.getTargetEntries(TargetReference.java:144)     在   org.mapstruct.ap.internal.model.source.TargetReference $ BuilderFromTargetMapping.build(TargetReference.java:120)     在   org.mapstruct.ap.internal.model.source.Mapping.init(Mapping.java:227)     在   org.mapstruct.ap.internal.model.source.SourceMethod $ Builder.build(SourceMethod.java:207)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.getMethodRequiringImplementation(MethodRetrievalProcessor.java:257)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.getMethod(MethodRetrievalProcessor.java:193)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.retrieveMethods(MethodRetrievalProcessor.java:148)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.retrieveMethods(MethodRetrievalProcessor.java:163)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.retrieveMethods(MethodRetrievalProcessor.java:163)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.retrieveMethods(MethodRetrievalProcessor.java:163)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.retrieveMethods(MethodRetrievalProcessor.java:163)     在   org.mapstruct.ap.internal.processor.MethodRetrievalProcessor.retrieveMethods   ...

我的域名类如下

            @Entity
            public class User implements FirstClassDomainObject {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private long id;
                private String name;
                private String email;
            ...

            @Entity
            public class Exercise implements FirstClassDomainObject {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private long id;
                private String name;
                private String description;
            ...

            @Entity
            public class WorkoutSet implements FirstClassDomainObject {
                @Id
                @GeneratedValue(strategy = GenerationType.IDENTITY)
                private long id;
                private int repetition;
                private double wight;
                private LocalDateTime timestamp;
                @ManyToOne
                private Exercise exercise;
                @ManyToOne
                private User user;
            ...

我的DTO课程如下

            public class UserResource implements ResourceObject {
                private Long id;
                private String name;
                private String email;
            ...

            public class ExerciseResource implements ResourceObject {
                private String name;
                private String description;
            ...

            public class WorkoutSetResource implements ResourceObject {
                private int repetition;
                private double wight;
                @JsonSerialize(using = LocalDateTimeSerializer.class)
                private LocalDateTime timestamp;
                private ExerciseResource exercise;
                private UserResource user;
            ...

我的mapper界面如下

            @Mapper(componentModel = "spring")
            interface UserMapper extends ClassMapper<User, UserResource> {
                @Override
                default List<Class<?>> getSupportedClasses() {
                    return Lists.newArrayList(User.class, UserResource.class);
                }
            }


            @Mapper(componentModel = "spring")
            interface ExerciseMapper extends ClassMapper<Exercise, ExerciseResource> {
                @Override
                default List<Class<?>> getSupportedClasses() {
                    return Lists.newArrayList(Exercise.class, ExerciseResource.class);
                }
            }

            @Mapper(componentModel = "spring", uses = {UserMapper.class, WorkoutSetMapper.class})
            interface WorkoutSetMapper extends ClassMapper<WorkoutSet, WorkoutSetResource> {
                @Override
                default List<Class<?>> getSupportedClasses() {
                    return Lists.newArrayList(WorkoutSet.class, WorkoutSetResource.class);
                }
            }

ClassMapper定义如下

            public interface ClassMapper<D extends DomainObject, R extends ResourceObject> {
                R map(D domainObject);
                D map(R resourceObject);
                List<Class<?>> getSupportedClasses();
            }

我省略了getter和setter方法以避开文本墙,但可以在此处找到整个代码库https://github.com/tonsV2/Lift-Log-Backend。 关于我做错了什么的任何线索?

1 个答案:

答案 0 :(得分:3)

我发现了错误!我已经将WorkoutSetMapper设置为自己使用。

@Mapper(componentModel = "spring", uses = {UserMapper.class, WorkoutsetMapper.class})
interface WorkoutSetMapper extends ClassMapper<WorkoutSet, WorkoutSetResource> {

虽然我应该有

@Mapper(componentModel = "spring", uses = {UserMapper.class, ExerciseMapper.class})
interface WorkoutSetMapper extends ClassMapper<WorkoutSet, WorkoutSetResource> {