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

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

JPA and Lombok causing StackOverflowError in circular dependency

问题

我有两个实体类:

  1. @Data
  2. @Entity(name = "user")
  3. @Table(name = "tbl_user")
  4. @EqualsAndHashCode(callSuper = true, exclude = "products")
  5. public class UserEntity extends BaseEntity {
  6. @Column(unique = true)
  7. private String username;
  8. @ToString.Exclude
  9. private String password;
  10. @Transient
  11. @JsonProperty("remember_me")
  12. private Boolean rememberMe;
  13. @Enumerated(EnumType.STRING)
  14. @CollectionTable(name = "tbl_user_role")
  15. @ElementCollection(fetch = FetchType.EAGER)
  16. Set<Role> roles = new HashSet<>();
  17. @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  18. private List<ProductEntity> products = new ArrayList<>();
  19. }
  1. @Data
  2. @Entity
  3. @Table(name = "tbl_product")
  4. @EqualsAndHashCode(callSuper = true)
  5. public class ProductEntity extends BaseEntity {
  6. @ManyToOne
  7. @JoinColumn(name = "user_id", nullable = false)
  8. private UserEntity user;
  9. private String productName;
  10. }

两者都继承自 BaseEntity

  1. @MappedSuperclass
  2. public abstract class BaseEntity implements Serializable {
  3. @Id
  4. @GeneratedValue(strategy = GenerationType.IDENTITY)
  5. private long id;
  6. @Version
  7. private long version;
  8. @Override
  9. public boolean equals(Object o) {
  10. if (this == o) return true;
  11. if (o == null || getClass() != o.getClass()) return false;
  12. BaseEntity that = (BaseEntity) o;
  13. return Objects.equals(id, that.id) && Objects.equals(version, that.version);
  14. }
  15. @Override
  16. public int hashCode() {
  17. return Objects.hash(id, version);
  18. }
  19. }

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

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

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

英文:

I have two entity classes:

  1. @Data
  2. @Entity(name = &quot;user&quot;)
  3. @Table(name = &quot;tbl_user&quot;)
  4. @EqualsAndHashCode(callSuper = true, exclude = &quot;products&quot;)
  5. public class UserEntity extends BaseEntity {
  6. @Column(unique = true)
  7. private String username;
  8. @ToString.Exclude
  9. private String password;
  10. @Transient
  11. @JsonProperty(&quot;remember_me&quot;)
  12. private Boolean rememberMe;
  13. @Enumerated(EnumType.STRING)
  14. @CollectionTable(name = &quot;tbl_user_role&quot;)
  15. @ElementCollection(fetch = FetchType.EAGER)
  16. Set&lt;Role&gt; roles = new HashSet&lt;&gt;();
  17. @OneToMany(mappedBy = &quot;user&quot;, fetch = FetchType.EAGER, cascade = CascadeType.ALL)
  18. private List&lt;ProductEntity&gt; products = new ArrayList&lt;&gt;();
  19. }
  1. @Data
  2. @Entity
  3. @Table(name = &quot;tbl_product&quot;)
  4. @EqualsAndHashCode(callSuper = true)
  5. public class ProductEntity extends BaseEntity {
  6. @ManyToOne
  7. @JoinColumn(name = &quot;user_id&quot;, nullable = false)
  8. private UserEntity user;
  9. private String productName;
  10. }

both extending a baseEntity:

  1. @MappedSuperclass
  2. public abstract class BaseEntity implements Serializable {
  3. @Id
  4. @GeneratedValue(strategy = GenerationType.IDENTITY)
  5. private long id;
  6. @Version
  7. private long version;
  8. @Override
  9. public boolean equals(Object o) {
  10. if (this == o) return true;
  11. if (o == null || getClass() != o.getClass()) return false;
  12. BaseEntity that = (BaseEntity) o;
  13. return Objects.equals(id, that.id) &amp;&amp; Objects.equals(version, that.version);
  14. }
  15. @Override
  16. public int hashCode() {
  17. return Objects.hash(id, version);
  18. }
  19. }

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:

确定