美文网首页
@EqualsAndHashCode 造成的 java.lang

@EqualsAndHashCode 造成的 java.lang

作者: 燃灯道童 | 来源:发表于2022-12-13 22:59 被阅读0次

问题:在用OneToMany保存一对多的数据时,报堆栈信息异常Handler dispatch failed; nested exception is java.lang.StackOverflowError。点击报错的行,竟然定位到类上的@Data注解。

解决方法

  1. 把@data注解替换成@Getter、@Setter和@ToString;
    并且去掉@EqualsAndHashCode或者自定义equals(Object other) 和 hashCode()方法,比如有些类只需要判断主键id是否相等即足矣。
  2. 用@Data注解并再加上@EqualsAndHashCode(callSuper = false, exclude={"giftSetList"}),排除掉相互引用的属性即可。

原因
我这面报错的原因是交叉引用了,在A entity中OneToMany引用多个B entity
在B entity中ManyToOne映射了一个A entity,具体逻辑可以看下面的代码。

这里面牵涉到两个点:

  1. @Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。
    所以在报错行指向@Data注解,因为交叉引用,@EqualsAndHashCode循环引用就会报堆栈异常。

  2. @EqualsAndHashCode 这个注解标在子类上

a. callSuper = true,根据子类自身的字段值和从父类继承的字段值来生成hashcode,当两个子类对象比较时,只有子类对象的本身的字段值和继承父类的字段值都相同,equals方法的返回值是true。

b. callSuper = false,根据子类自身的字段值 来生成hashcode, 当两个子类对象比较时,只有子类对象的本身的字段值相同,父类字段值可以不同,equals方法的返回值是true。

调整后的代码
PostgreSQLGiftSetTagEntity和PostgreSQLGiftSetEntity的关系是一对多。PostgreSQLGiftSetTagEntity中的@OneToMany下面对应的是多个PostgreSQLGiftSetEntity;同时PostgreSQLGiftSetEntity中的@ManyToOne下对应的是一个PostgreSQLGiftSetTagEntity。
这两个entity交叉引用,如果用@EqualsAndHashCode注解无论是ture还是false都会出现java.lang.StackOverflowError。
使用@EqualsAndHashCode(callSuper = false, exclude={"giftSetList"})注解的意思就是把交叉引用的部分去掉。

@Data
@Builder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false, exclude={"giftSetList"})
@AllArgsConstructor
@Entity
@Table(name = "gift_set_tag")
public class PostgreSQLGiftSetTagEntity extends PostgreSQLUnpartitionedEntity implements GiftSetTag {

    @Column(name = "image", nullable = false)
    private String image;

    @Column(name = "name", nullable = false)
    private String name;

    @OneToMany(targetEntity = PostgreSQLGiftSetEntity.class, fetch = FetchType.EAGER, mappedBy = "giftSetTag",orphanRemoval = true)
    @Fetch(FetchMode.SUBSELECT)
    @Cascade(CascadeType.ALL)
    @OrderBy(clause = "displayOrder")
    private Set<PostgreSQLGiftSetEntity> giftSetList;
}
@Data
@Builder
@NoArgsConstructor
@EqualsAndHashCode(callSuper = false, exclude={"giftSetTag"})
@AllArgsConstructor
@Entity
@Table(name = "gift_set")
public class PostgreSQLGiftSetEntity extends PostgreSQLUnpartitionedEntity implements GiftSet {

    @Column(name = "sku_ids", nullable = false)
    private String skuIds;

    @Column(name = "tag_id", insertable=false, updatable=false)
    private String tagId;

    @Column(name = "image", nullable = false)
    private String image;

    @Column(name = "thumbnail_image", nullable = false)
    private String thumbnailImage;

    @Column(name = "description")
    private String description;

    @Column(name = "display_order")
    private Integer displayOrder;

    @Column(name = "engrave_skus")
    @Convert(converter = EngraveSkusConverter.class)
    private Set<String> engraveSkus;

    @JoinColumn(name="tag_id")
    @ManyToOne(targetEntity=PostgreSQLGiftSetTagEntity.class)
    private PostgreSQLGiftSetTagEntity giftSetTag;
}

参考链接:
https://blog.csdn.net/dj1955/article/details/123822789
https://www.656463.com/wenda/jiazaiguanxishiduizhanyichu_363
https://blog.csdn.net/m0_57037182/article/details/124704408
https://blog.csdn.net/c851204293/article/details/96989512
https://www.jianshu.com/p/d318ba2e84da

相关文章

网友评论

      本文标题:@EqualsAndHashCode 造成的 java.lang

      本文链接:https://www.haomeiwen.com/subject/xxnhqdtx.html