Lombok @EqualsAndHashCode 配置自定义hashCode方法

  • 目录
    • 背景
    • 问题
    • 原因
    • 解决办法
    • 参考:

目录

背景

Entity
一个User包含多个AbstractUser。在jpa查询中因为用到left join fetch,导致查询结果AbstractUser重复,而又没有办法在第二层利用distinct关键字去重AbstractUser,所以利用SET来过滤。但是利用Lombok的@DATA注解导致错误。

User

@Entity
@Table(name = "user")
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class User{@Id@GeneratedValue@Column(name = "uuid")private UUID id;@Column(name = "name", nullable = false)private String name;@OneToMany(mappedBy = "user", fetch = FetchType.LAZY)private Set<AbstractUser> abstractUsers;
}

AbstractUser

@Entity
@Table(name = "abstract_user")
@Slf4j
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class AbstractUser implements Serializable{/*** *//** The unique identifier */@GeneratedValue(generator = "system-uuid")@GenericGenerator(name = "system-uuid", strategy = "uuid")@Column(name = "uuid", unique = true, nullable = false)@Idprivate String id;@ManyToOne(fetch = FetchType.LAZY)@JoinColumn(name = "user_id")@JsonIgnoreprivate User user;
}

利用下面的JPA语句查询的时候报错了

@Query("select distinct u from User u left join fetch u.abstractUsers as au "+ "where (:username is null or lower(u.name)=lower(:username)) "+ "and (:abstractUserId is null or au.id=:abstractUserId ")List<User> findUsers(@Param("username") String username, @Param("abstractUserId") String abstractUserId);

问题

java.lang.NullPointerException: null
at org.hibernate.engine.internal.StatefulPersistenceContext.getLoadedCollectionOwnerOrNull(StatefulPersistenceContext.java:789) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.event.spi.AbstractCollectionEvent.getLoadedOwnerOrNull(AbstractCollectionEvent.java:58) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.event.spi.InitializeCollectionEvent.(InitializeCollectionEvent.java:22) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.internal.SessionImpl.initializeCollection(SessionImpl.java:2244) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection$4.doWork(AbstractPersistentCollection.java:580) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:262) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:576) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:147) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at org.hibernate.collection.internal.PersistentSet.hashCode(PersistentSet.java:458) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
at com.test.AbstractUser.hashCode(AbstractUser.java:43) ~[classes/:na]
at java.util.HashMap.hash(Unknown Source) ~[na:1.8.0_151]
at java.util.HashMap.put(Unknown Source) ~[na:1.8.0_151]
at java.util.HashSet.add(Unknown Source) ~[na:1.8.0_151]
at java.util.AbstractCollection.addAll(Unknown Source) ~[na:1.8.0_151]

原因

@Data相当于@Getter @Setter @RequiredArgsConstructor @ToString ``@EqualsAndHashCode这5个注解的合集。
当使用@Data注解时,则有了@EqualsAndHashCode注解,那么就会在此类中存在equals(Object other) 和 hashCode()方法,且不会使用父类的属性,这就导致了可能的问题。
比如,有多个类有相同的部分属性,把它们定义到父类中,恰好id(数据库主键)也在父类中,那么就会存在部分对象在比较时,它们并不相等,却因为lombok自动生成的equals(Object other) 和 hashCode()方法判定为相等,从而导致出错。
hashSet过滤去重的时候使用hashCode方式生成的hashcode来判别对象是否重复。lombok的@Data注解生成的hashCode()导致出错。

解决办法

  1. 使用@Getter`` @Setter`` @ToString代替@Data并且自定义equals(Object other) 和 hashCode()方法,比如有些类只需要判断主键id是否相等即足矣。
  2. 或者在使用@Data时同时加上@EqualsAndHashCode(callSuper=true)注解。本文情况因为没有父类,所以这个方法不适用,如果有用到父类的话可以使用。
  3. 如果没有父类的话,使用@DATA同时加上@EqualsAndHashCode(of = {"id"})。指定仅使用id属性,如果有多个可以确定对象唯一的属性的话也可以继续在{}中添加。
  4. 使用@DATA同时加上@EqualsAndHashCode(onlyExplicitlyIncluded = true),然后在需要执行的属性加上@EqualsAndHashCode.Include,如:
/** The unique identifier */@GeneratedValue(generator = "system-uuid")@GenericGenerator(name = "system-uuid", strategy = "uuid")@Column(name = UNIQUE_ID_COLUMN_NAME, unique = true, nullable = false)@Id@EqualsAndHashCode.Includeprivate String id;

参考:

https://stackoverflow.com/questions/33893122/jpa-hibernate-find-throws-nullpointerexception.
https://blog.csdn.net/zhanlanmg/article/details/50392266.
http://www.javabyexamples.com/delombok-equalsandhashcode/

Lombok @Data导致的hashCode的问题相关推荐

  1. Lombok的@Data生成的hashCode和equals方法坑

    一.场景复现 创建两个lombok的@Data注解的类Pig实例,放进HashMap当key,map里面的数据居然被覆盖了. package com.mk;import lombok.Data; @D ...

  2. Lombok,@Data - Generating equals/hashCode implementation but without a call to superclass

    简而言之,在具有继承关系的场景下 在子类中使用@Data后,equals/hashCode会被复写成只与子类字段的相关的逻辑 比较两个子类对象是否相等时,即使子类字段相等,但从父类继承来的字段不相等, ...

  3. lombok @data 忽略属性_Lombok使用指南

    作者 | Louis码农工具人 来源 | urlify.cn/fEJzUv 一.Lombok 简介 Lombok 是一款 Java 开发插件,使得 Java 开发者可以通过其定义的一些注解来消除业务工 ...

  4. MySQL Sending data导致查询很慢的问题详细分析

    这两天帮忙定位一个MySQL查询很慢的问题,定位过程综合各种方法.理论.工具,很有代表性,分享给大家作为新年礼物:) [问题现象] 使用sphinx支持倒排索引,但sphinx从mysql查询源数据的 ...

  5. lombok @data 忽略属性_使用lombok编写优雅的Bean对象

    题外话:欢迎将公众号设置为星标,技术文章第一时间看到.我们将一如既往精选技术好文,提供有价值的阅读.如有读者想要投稿,可以在公众号任意文章下留言,技术博主奖励丰厚. 推荐阅读 1. SpringBoo ...

  6. 使用Arthas热更新时,lombok注解导致mc命令编译失败

    看Arthas文档,其中代码热更新vb.net教程功能很吸引人,用文档的demo项目热更新,没有c#教程任何问题. 但是,用公司项目的代码一试,mc编译时报错. 网上查了很多博客,有python基础教 ...

  7. java.lang.ClassNotFoundException: lombok.Data

    原因:mysql datetime类型,实体类 写成了 Data 方案:把所有的实体类,还有可能不在一个包下的扩展实体类找到(博主就是耗在这里忘记了还有个扩展实体类),Data改成Date 耗时:20 ...

  8. lombok @Data注解打印时不会打印父类属性

    1.在切面中打印日志时,并没有打印出父类属性,多方查找后,得到如下结果 @Data注解默认只会打印当前类属性,并不会打印父类属性 解决方案如下 1)打印时格式化 Object[] args = pjp ...

  9. 小程序canvas画画板签字版,touchmove时卡顿的问题(根本原因是因为vue语法中page.data导致视图层和逻辑层的频繁通讯导致)

    起因 因为要做一个画画板的功能,所以使用了canvas组件,一开始好多人说小程序canvas性能特别差,也没太注意,做出来之后确实有点卡,而且每一笔touchmove时间越长越卡,最终导致页面卡到无法 ...

最新文章

  1. /dev/tcp 的简单应用
  2. 微信公众号php提交表单,PHP教程:使用YII2框架实现微信公众号中表单提交功能...
  3. 计算机基础理论知识的论文,计算机基础毕业论文
  4. 设计模式的C语言应用-导言-第一章
  5. GSM掉话原因(网优的基础知识)
  6. 大数据分析工具鄙视链:Python成老大,Excel小弟都称不上?
  7. python3多进程 queue 取值_python3.4.3 多进程之间结果变量的传递问题,程序无任何结果输出...
  8. 学html和css的感受
  9. r语言html帮助是什么东西,R语言帮助的使用
  10. lora三层服务器协议,lorawan协议(lora无线传输协议与HTTP协议)
  11. 周立功开发板安装linux,极速搭建周立功IMX283A ARM Linux开发环境(1)
  12. Clion 报错 Cannot save file ... [Failed to reload]
  13. 概率论知识回顾(十):二维连续随机变量分布函数和联合密度函数
  14. 处理器最新排行_鲁大师Q2季度PC硬件排行:Intel十代酷睿初入战局,最受欢迎CPU是它...
  15. PCBA加工波峰焊空焊原因及对策
  16. 怎么把pdf转换成高清图片
  17. 亚当斯密的“看不见的手”
  18. CEO卡莉被驱逐,惠普何去何从?
  19. [附源码]Java计算机毕业设计SSM高校学生综合素质测评系统
  20. 5GNR标准第15章

热门文章

  1. 【OFDM】OFDM正交频分复用---入门总结
  2. 技术Leader的30条军规
  3. vue z-index层级显示问题
  4. MSXML2.XMLHTTP
  5. Thinkphp中的assign() 和 display()
  6. 内存拷贝函数memcpy相关解析(C语言)
  7. webrtc服务器开发--搭建环境
  8. ListIterator
  9. iphone修改密码时服务器,iPhone 突然弹出窗口要求修改密码怎么办?
  10. 为什么不建议用Executors?