我使用的是 hibernate 4.3.10。
当引用复合主键时,我的实体看起来像下一个(从@Master Slave得到答案后添加了equals()和hashCode()):
@Entity
@Table(name="compositepk")
public class Car {
@EmbeddedId
private CarPK carPK;
private String name;
public CarPK getCarPK() {
return carPK;
}
public void setCarPK(CarPK carPK) {
this.carPK = carPK;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Embeddable
public static class CarPK implements Serializable{
private static final long serialVersionUID = -5202331188724915048L;
private int chassisNumber;
private int engineNumber;
public int getChassisNumber() {
return chassisNumber;
}
public void setChassisNumber(int chassisNumber) {
this.chassisNumber = chassisNumber;
}
public int getEngineNumber() {
return engineNumber;
}
public void setEngineNumber(int engineNumber) {
this.engineNumber = engineNumber;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof CarPK) {
CarPK car = (CarPK)obj;
if(this.getChassisNumber().intValue() == car.getChassisNumber().intValue() &&
this.getEngineNumber().intValue() == car.getEngineNumber().intValue()) {
return true;
} else {
return false;
}
}
return false;
}
@Override
public int hashCode() {
return this.chassisNumber.hashCode()+this.engineNumber.hashCode();
}
}
}
hibernate 文档说我们必须在复合主键中实现 equals() 和 hashCode()。
但是,我发现在 CarPK 中不重写它们并没有任何问题。我可以比较汽车并将它们添加到 Set 中并获得正确的结果。例如下面是比较代码:
Car.CarPK pk = new Car.CarPK();
pk.setChassisNumber(3);
pk.setEngineNumber(2017);
Car c1 = (Car) session1.get(Car.class, pk);
Car c2 = (Car) session2.get(Car.class, pk);
if(c1.equals(c2)) {
System.out.println("==");
} else {
System.out.println("!=");
}
此代码打印“!=”,如果chassisNumber 和engineNumber 相同,则打印“==”。
(修改上面的代码后,在不同的 session 中得到相同的结果,上面的代码打印“!=”,为什么?它不应该打印出“==”,因为我已经实现了 equals( )和 hashCode()?)
那么有人可以告诉我当我没有在 CarPK 中实现 equals() 和 hashCode() 时出现的问题吗?
提前致谢!
最佳答案
我花了一些时间才弄清楚,但您还必须重写 Car
中的 equals
和 hashCode
@Override
public boolean equals(Object obj) {
if(obj instanceof Car) {
Car that = (Car) obj;
return this.carPK.equals(that.carPK);
}
return false;
}
@Override
public int hashCode() {
return this.carPK.hashCode();
}
顺便说一句,您在 CarPK
中的 hashCode
实现是危险的(并且是 false,因为它无法编译)。生成 2 个具有相同 hashCode
但不 equals
CarPK
太容易了
Car.CarPK pk1 = new Car.CarPK();
pk1.setChassisNumber(3);
pk1.setEngineNumber(2017);
Car.CarPK pk2 = new Car.CarPK();
pk2.setChassisNumber(1500);
pk2.setEngineNumber(520);
System.out.println(pk1.hashCode()); //prints 2020
System.out.println(pk2.hashCode()); //prints 2020
//Same hashCode, should be equal, just checking...
System.out.println(pk1.equals(pk2)); //prints false !
我建议您采用这种更难产生冲突的实现
@Override
public int hashCode() {
return Objects.hash(chassisNumber, engineNumber);
}
关于java - hibernate复合主键中存在find而不覆盖equals和hashCode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35828119/