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
进行类似的限制以防止递归无限循环。
我正在尝试制作 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
进行类似的限制以防止递归无限循环。