lombok中的@Data如何创建构造函数

问题描述 投票:0回答:2

好的,所以我在这里读了很多问题,但仍然无法理解它是如何工作的并且没有给出错误。按照我的逻辑,如果 @Data 有final 字段,它就会创建一个RequiredConstructor。 @Entity 需要一个 noArgConstructor 所以我也做了它。 这是我的用户类:

@Data
@Entity
@NoArgsConstructor(force = true)
public class User implements UserDetails {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    private final String username;
    private final String password;
    private final String fullname;
    private final String street;
    private final String city;
    private final String state;
    private final String zip;
    private final String phoneNumber;

}

但是现在在另一个类中,如果我想创建一个如下所示的新 User 对象,我无法做到。

public User toUser(PasswordEncoder passwordEncoder) {
        return new User(username, passwordEncoder.encode(password),
                fullname, street, city, state, zip, phone);
    }

编辑:我将 @RequiredArgConstructor 添加到 User 类中,现在它不会给我错误。问题已解决,但我不明白它是如何工作的。

java spring spring-boot spring-data-jpa lombok
2个回答
1
投票

当您添加

@NoArgsConstructor
时,它会覆盖
@RequiredArgsConstructor
中的
@Data
,这会强制您指定它。但是,如果您有最终字段,则您不想使用 NoArgsConstructor,因为在构造之后,无法设置它们,因此它们永远不会有值。

另外,请注意,您真的不想将@Data与@Entity一起使用,主要是因为它附带的EqualsAndHashcode。


1
投票

@Data
@RequiredArgsConstructor
不同。它将为您生成所需的 args 构造函数仅当未编写构造函数时。在这里,您did编写了一个构造函数 -
@NoArgsConstructor
执行此操作。

因为你有无参数构造函数。您可以添加

@RequiredArgsConstructor
,现在 lombok 也会制作它。

这里有无参数构造函数很奇怪,因为它只会将所有字段初始化为

null
。 JPA 对实体代表什么感到困惑,并且没有给出明确的答案。如果您认为
User
实例代表一个用户,lombok 的 equals 基本上没问题,但您应该排除 ID 字段,因为这是在数据库中存储用户对象的实现细节,而不是用户对象身份的固有方面。当然,这确实意味着一个简单的 equals 调用会查询整个数据库,但这是 JPA 的一个天然缺点。

或者,您可以说

User
的实例代表 数据库中的一行,在这种情况下,编写符合该含义和
equals
契约的完全正确的 equals 实现的唯一方法就是这个 bizarroworld施工:

  • 如果
    id
    null
    (即您创建了一个新实例并且尚未使用 JPA 保存它),那么它的 equals impl 是:
    return this == o;
    - 就像这样,它只能等于它自己,即使每个字段都是相同的它不能与另一个字段相等。毕竟,如果您都
    save()
    ,您将获得 2 行。
  • 如果
    id
    不为空,则相等性仅由 id 定义,而不是其他任何东西,出于同样的原因 - 如果您要修改一个,则无法修改另一个,然后调用某些 save()调用你最终仍然只有一行。
    
    
  • 以我非常有限的经验(我不使用 JPA)来看,JPA 教程和指南往往只是做他们想做的事,而且很少与实用主义(不要引起“查询世界”问题)或 equals 规范相一致。 Lombok 的同等功能可能不是您想要的 JPA 东西。话又说回来,确实没有任何“有效”的 equals 实现(它会产生某种非常令人惊讶和不受欢迎的行为)。

注意:我是 lombok 的核心开发人员之一。

© www.soinside.com 2019 - 2024. All rights reserved.