Lombok Hibernate 实体 HashMap.hash 上的 StackOverflowError

StackOverflowError on HashMap.hash for Lombok Hibernate Entities

我正在尝试制作 spring 启动应用程序。我想为每个用户设置目标。但我收到错误:

java.lang.WhosebugError: null
at java.base/java.util.HashMap.hash(HashMap.java:339) ~[na:na]
at java.base/java.util.HashMap.get(HashMap.java:552) ~[na:na e.t.c.

目标:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private User userss;

在用户中:

@OneToMany(mappedBy = "userss", fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
private Set<Goal> goalSet = new HashSet<>();

以及每个用户接收目标的方法:

@Override
public Set findByUserId(Long userId){
   return (Set) getSession().createQuery("from Goal where userss.id =:userId").setParameter("userId", userId).stream().collect(Collectors.toSet());
}

接收所有用户及其目标的方法:

@Override
@SuppressWarnings("unchecked")
public Set getGoals() {
    return (Set) getSession().createQuery("from Goal").stream().collect(Collectors.toSet());
}

我将 lombok 用于哈希(实际上用于其他基本方法)

如果您的实体使用 Lombok,则必须限制生成器

@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true) // important
public class User {

    @Id
    @EqualsAndHashCode.Include // important, only on the PK
    UUID id;

    // Other fields not included in the generator
}

这是因为,默认情况下,Lombok 为实体的每个字段生成方法 Equals 和 HashCode,但 Hibernate 要求只在 @Id 字段上进行相等。

您必须为所有实体执行此操作。

为什么会崩溃?

因为目标引用了用户,而用户引用了目标;当默认生成器实现 Equals 和 HashCode 时,它​​会无限地来回调用这两个实例,直到崩溃。

即使没有这种循环引用,如果没有适当的 Equals 和 HashCode,Hibernate 也不知道如何处理其缓存中的实体。

您可能需要对 @ToString 进行类似的限制以防止递归无限循环。