【问题标题】:Room not finding lombok generated constructor房间找不到 lombok 生成的构造函数
【发布时间】:2018-07-05 10:19:38
【问题描述】:

我正在使用 lombok 为我的模型生成构造函数、getter 和 setter。当我尝试使用 lombok 为我的实体类生成构造函数时,出现此错误

Error:(14, 8) error: Entities and Pojos must have a usable public 
constructor. You can have an empty constructor or a constructor whose 
parameters match the fields (by name and type).
Tried the following constructors but they failed to match:
Region(int,java.lang.String,java.lang.String) -> [param:arg0 -> matched 
field:unmatched, param:arg1 -> matched field:unmatched, param:arg2 -> 
matched field:unmatched]

但是手动编写构造函数是可行的。谁能帮我找出问题所在?

我的实体类如下所示

@Value
@Entity
public class Region {
    @PrimaryKey
    private int regionId;
    private String name;
    private String code;
}

房间版本:1.1.0 龙目岛版本:1.16.20

【问题讨论】:

    标签: android android-room lombok


    【解决方案1】:

    匹配似乎失败,因为构造函数参数名称在运行时不可用。 由于版本 1.16.20 lombok 不再生成 @ConstructorProperties 注释(将带有这些名称)。 尝试将lombok.anyConstructor.addConstructorProperties = true 添加到您的lombok.config,lombok 将为您的构造函数生成一个@ConstructorProperties 注释。 (有关如何配置 lombok 的详细信息,请参阅https://projectlombok.org/features/configuration。)

    编辑:问题是编译期间的注释处理。 Room 和 lombok 都作为注释处理器钩入 javac,它们不能很好地结合使用。所以目前唯一稳定的办法就是先delombok。

    【讨论】:

    • 添加 lombok.anyConstructor.addConstructorProperties = true 会导致构建失败并出现错误:找不到符号类 ConstructorProperties。从这个 link ,它说注释不可用。
    • 你可能有JDK 9或更高版本,这就是它不再默认生成的原因。您可以尝试将包含模块java.desktop 包含到您的模块路径中吗? (我不确定在 android 版本上这是否可行……)
    • 我实际上在使用 JDK 8
    • 看来注解在Android上一般不可用。有趣的是您的手动构造函数有效。在这种情况下,参数名称似乎以某种方式存在(或使用其他机制让 Room 正确匹配参数。但是,我无法在 Room 文档中找到匹配过程的详细信息。
    • 可能问题出在构建过程中? lombok annotationProcessor 是否在 Room 处理器之前调用?
    【解决方案2】:

    您可以使用以下设置:

    @Entity
    @Getter
    @Setter
    @AllArgsConstructor(onConstructor = @__({@Ignore}))
    @NoArgsConstructor
    public class Region {
        @PrimaryKey
        private int regionId;
        private String name;
        private String code;
    }
    

    这将使 Room 使用默认构造函数并通过提供的设置器设置值。此外,您还有一个构造函数,它接受对象实例化的所有参数,但会被 Room 忽略。

    注意:对象不会是不可变的

    【讨论】:

    • 欢迎来到 StackOverflow。感谢您花时间解释您的答案。但是你能解释一下这两个构造函数注释具体是做什么的吗?问候。
    • 谢谢。 @AllArgsConstructor 将为类的所有字段生成一个构造函数。使用onConstructor = @__({@Ignore}) 参数,我们告诉lombok 将@Ignore 注释添加到生成的构造函数中。这将使 Room 忽略此构造函数。相反,@NoArgsConstructor 只是为这个类提供了一个默认构造函数,Room 将使用它来实例化对象。所以你实际上可以离开@AllArgsConstructor(onConstructor = @__({@Ignore}))。如果您必须自己实例化这些对象,它会很方便。
    【解决方案3】:

    请使用@Data 注释尝试如下。

        @Value
        @Entity
        @Data
        public class Region {
            @PrimaryKey
            private int regionId;
            private String name;
            private String code;
        }
    

    【讨论】:

      猜你喜欢
      • 2019-08-21
      • 1970-01-01
      • 2021-06-14
      • 2016-12-09
      • 2019-10-16
      • 2020-12-09
      • 2017-06-26
      • 2021-12-15
      • 1970-01-01
      相关资源
      最近更新 更多