好了,我在这里读了很多问题,仍然不能理解这是如何工作的,也没有给出错误。根据我的逻辑,如果@Data有final字段,它会创建一个空的构造函数。@Entity需要一个noArgConstructor,所以我也做了它。这是我的User类:
@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);
}
型
编辑:我添加了@ RedArgConstructor到User类,现在它不会给我给予错误。问题是固定的,但我不明白它是如何工作的。
2条答案
按热度按时间omtl5h9j1#
当你添加
@NoArgsConstructor
时,它会覆盖@Data
中的@RequiredArgsConstructor
,这会迫使你指定它。但是,如果你有final字段,你不想使用NoArgsConstructor,因为在构造之后,没有办法设置它们,所以它们永远不会有值。另外,请注意,您真的不想将@Data与@Entity一起使用,主要是因为它附带的HashCode。
3okqufwl2#
@Data
和@RequiredArgsConstructor
不一样。它会为你生成所需的args构造函数只有在没有写构造函数的情况下。这里,你 * 确实 * 写了一个构造函数-@NoArgsConstructor
就是这么做的。因为你有一个无参数的构造函数,你可以添加
@RequiredArgsConstructor
,现在lombok也会创建它。在这里使用无参数构造函数是很奇怪的,因为它只会将所有字段初始化为
null
。JPA对实体表示什么感到困惑,并且没有给予明确的答案。如果您认为User
示例表示User,那么lombok的equals基本上是可以的,但是您应该排除ID字段,因为这是在数据库中存储用户对象的实现细节,而不是用户对象标识的固有方面。当然,这确实意味着一个简单的等于调用查询整个数据库,但这是JPA的一个自然缺陷。或者,你可以说
User
的一个示例代表 * 数据库中的一行 *,在这种情况下,编写一个完全正确的equals实现的唯一方法,既符合equals
的含义,又符合equals
的契约,就是这个奇怪的世界结构:id
是null
(即,您创建了一个新示例,但尚未使用JPA保存它),则其equals impl为:return this == o;
-如中所示,它只能等于自身,即使每个字段都相同它也不能等于另一个。毕竟,如果您save()
两者都相同,您将得到2行。id
不为null,则相等性由id
单独定义,而不是其他任何东西,出于同样的原因-如果您要修改一个,但未能修改另一个,然后调用一些保存()调用,您最终仍然只得到一行。JPA教程和指南在我非常有限的经验(我不使用JPA)倾向于做他们喜欢的任何事情,这与实用主义很少一致(不要引起“查询世界”的问题)或equals规范。Lombok的equals可能不是您想要的JPA东西。实际上没有任何equals的实现是“有效的”(它会有一些非常令人惊讶和不希望的行为)。
NB:我是Lombok的核心开发者之一。