我有一个使用 JPA 和 Lombok 的 Spring Boot 项目,其中我在数据库中的用户和角色实体之间使用多对多关系。我的目标是显示用户及其关联的角色,但我没有获取角色,而是得到一个空列表。
我的用户实体如下所示:
import jakarta.persistence.*;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import java.util.Set;
@Data
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Size(max = 255)
@Email
@Column(unique = true)
private String email;
@NotBlank
@Size(max = 255)
private String password;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "roles_users",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private Set<Role> roles;
}
我也有一个类似的 Role 实体。即使我在数据库中有数据并且我知道用户已分配角色,但在执行查询时我会得到一个具有空角色的用户列表。
我遇到的另一个问题与无限递归有关,尤其是在为用户分配两个以上角色时。
该问题与实体类(用户和角色)中 Lombok 的 @Data 注释有关。 @Data 注解根据类字段自动生成 equals()、hashCode()、toString() 等方法。当实体之间存在复杂关系(例如多对多关系)时,这可能会导致问题。
要解决这个问题,可以使用 Lombok 的 @EqualsAndHashCode.Exclude 注解从 equals() 和 hashCode() 自动生成中排除特定字段。这将防止无限递归以及与 Lombok 自动生成相关的其他问题。您应该将此注释应用于导致问题的字段,例如涉及多对多关系的字段。
此配置应有助于避免与自动方法生成相关的问题,并允许您正确地检索与表相关的数据。
用户实体
@Data
@Entity
public class User {
//Other fields
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "roles_users",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
@EqualsAndHashCode.Exclude // Exclude specific fields from the automatic generation
private Set<Role> roles;
}