JPA和Lombok在循环依赖中引起了StackOverflowError。

huangapple go评论82阅读模式
英文:

JPA and Lombok causing StackOverflowError in circular dependency

问题

我有两个实体类:

@Data
@Entity(name = "user")
@Table(name = "tbl_user")
@EqualsAndHashCode(callSuper = true, exclude = "products")
public class UserEntity extends BaseEntity {

    @Column(unique = true)
    private String username;

    @ToString.Exclude
    private String password;

    @Transient
    @JsonProperty("remember_me")
    private Boolean rememberMe;

    @Enumerated(EnumType.STRING)
    @CollectionTable(name = "tbl_user_role")
    @ElementCollection(fetch = FetchType.EAGER)
    Set<Role> roles = new HashSet<>();

    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List<ProductEntity> products = new ArrayList<>();
}
@Data
@Entity
@Table(name = "tbl_product")
@EqualsAndHashCode(callSuper = true)
public class ProductEntity extends BaseEntity {

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private UserEntity user;
    private String productName;
}

两者都继承自 BaseEntity

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Version
    private long version;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BaseEntity that = (BaseEntity) o;
        return Objects.equals(id, that.id) && Objects.equals(version, that.version);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, version);
    }
}

现在,当我尝试检索所有产品(或所有用户)(例如 findAll 方法),我会收到 StackOverflowError 错误。
我知道这个错误是由于用户和产品之间的循环依赖引起的,所以我在 UserEntity 的 equals 注解中添加了排除项来解决它,就像这样:

@EqualsAndHashCode(callSuper = true, exclude = "products")

不幸的是,错误仍然不断出现。我在这里漏掉了什么?

英文:

I have two entity classes:

@Data
@Entity(name = &quot;user&quot;)
@Table(name = &quot;tbl_user&quot;)
@EqualsAndHashCode(callSuper = true, exclude = &quot;products&quot;)
public class UserEntity extends BaseEntity {

    @Column(unique = true)
    private String username;

    @ToString.Exclude
    private String password;

    @Transient
    @JsonProperty(&quot;remember_me&quot;)
    private Boolean rememberMe;

    @Enumerated(EnumType.STRING)
    @CollectionTable(name = &quot;tbl_user_role&quot;)
    @ElementCollection(fetch = FetchType.EAGER)
    Set&lt;Role&gt; roles = new HashSet&lt;&gt;();

    @OneToMany(mappedBy = &quot;user&quot;, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private List&lt;ProductEntity&gt; products = new ArrayList&lt;&gt;();
}
@Data
@Entity
@Table(name = &quot;tbl_product&quot;)
@EqualsAndHashCode(callSuper = true)
public class ProductEntity extends BaseEntity {

    @ManyToOne
    @JoinColumn(name = &quot;user_id&quot;, nullable = false)
    private UserEntity user;
    private String productName;
}

both extending a baseEntity:

@MappedSuperclass
public abstract class BaseEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Version
    private long version;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BaseEntity that = (BaseEntity) o;
        return Objects.equals(id, that.id) &amp;&amp; Objects.equals(version, that.version);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, version);
    }
}

Now when I try to retrieve all products (or all users) (e.g. findAll method) I get a StackOverflowError.
I know this error is caused by the circular dependency between user and products, so I added an exclude to the equals annotation in the userEntity to resolve it, like so:<br><br> @EqualsAndHashCode(callSuper = true, exclude = &quot;products&quot;)

Unfortunately the error keeps popping up. What am I missing here?

答案1

得分: 1

如果有帮助的话,Lombok还有一个很有用的注解@EqualsAndHashCode.Exclude,非常适用于测试!

英文:

In case it might help, lombok also has anotation @EqualsAndHashCode.Exclude very useful for tests!

答案2

得分: 0

我通过在rolesuser类变量上添加@ToString.Exclude来解决了这个问题。显然后来在代码的某个地方我打印了它们,这导致了错误。

英文:

I managed to fix the issue by adding @ToString.Exclude to the roles and user class variables. Apparently I was printing them somewhere later in the code, which was causing the error.

huangapple
  • 本文由 发表于 2020年10月20日 01:13:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64432171.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定