hibernate不同条件查询结果集一样,主键@ID的原因
这一周在翻新公司的老项目,遇到了一些预想不到的事情。
其中一个是,使用hibernate查询,不同的查询条件,居然都查到同一条记录,感觉奇怪了,开始以为是session的原因;
后来发现是hibernate对主键有要求,看了数据库表设计,惨了,居然没有主键,我丢,好多表都没有主键,当时内心是郁闷的,什么人设计的?后来想想,这都十年前的项目了,十年前这个设计水平,也理解吧。
hibernate在数据表所对应的实体类有要求:必须有主键。因为数据表没有主键,于是最初我给其中一个非空字段标记为@Id,后来惨了,因为条件查询只要条件里有这个字段,查出来的都是这条数据。
解决方法:
构建联合主键:
将原来的实体类A分解为两个类:主键类A1 和 实体类A2
-
主键类A1:将联合主键的字段单独放在类中,该类实现 java.io.Serializable 接口,并重写 equals 和 hascode,再将该类注解为 @Embeddable
@Data @Embeddable public class BankParamKey implements Serializable { private String pmcd; private String pmtp; private String pmnm; @Override public boolean equals(Object obj) { return super.equals(obj); } @Override public int hashCode() { return super.hashCode(); } }
-
实体类A2:该类不包含联合主键类中的字段,但保存联合主键类的引用,并生成 set 和 get 方法(此处用lombok自动生成),并将该引用注解为 @Id
@Data @Entity @Table(name ="P019") public class BankParam implements Serializable { @Id private BankParamKey bankParamKey;//pmcd + pmtp + pmnm 组合主键 private String pmky; private String pmv4; private String pmv1; private String pmv5; private String pmv2; private String pmv3; }
这样就可用解决使用hibernate但是没有主键的表的问题了。