我有这个课程,我使用它作为@EmbeddedId
:
@Embeddable
public class Pk implements Serializable {
@NotNull
@Column( nullable = false)
private UUID id = UUIDGenerator.EMPTY_UUID;
@NotNull
@Column( nullable = false)
private String name = "";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
return this.id.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || !(obj instanceof PK)) {
return false;
}
Pk other = (Pk)obj;
return this.id.equals(other.getId());
}
}
但是,在决定何时应该创建新实体或更新现有实体时,SpringBoot Repository似乎没有使用equals()/ hashCode()函数。结果是应该被视为相等的两个实体,它们不是,并且存储库创建新条目而不是更新现有条目。
永远不会达到equals()中的断点,这让我想知道存储库是否正在使用它(使用SpringBoot 1.5.5)。
请注意,在相等性测试中只使用两个属性中的一个。另一个是自然键(总是唯一的,但不是不可变的)。
关于为什么会发生这种情况以及如何解决问题的任何想法?
提前致谢,
PS:这是使用它的类
@Entity
public class Demo {
@EmbeddedId
Pk pk = new Pk();
@NotNull
@Column(nullable = false)
private String dummy = "";
//getters and setters
}
这就是它的用法:
@Autowired
DemoRepository demoRepository;
public void updateDemo(Demo updatedDemo) {
Optional<Demo> oldDemo =
demoRepository.findByPkId(updatedDemo.getPk().getId());
//Do some sanity checks with the oldDemo
//Creates new entry, even though it should have updated the old
demoRepository.save(updatedDemo);
}
==
我正在再次编辑这个问题,因为经过一些调试我发现Hibernate确实没有调用hashCode()
中定义的@EmbeddedId
函数,而是通过实际求和来使用它自己的hashCode()
hashCode()
属性的@EmbeddedId
。
实际代码似乎位于org.hibernate.type.ComponentType.java
,其中Object x
属于PK
类型。
public int getHashCode(Object x, SessionFactoryImplementor factory) {
int result = 17;
for(int i = 0; i < this.propertySpan; ++i) {
Object y = this.getPropertyValue(x, i);
result *= 37;
if (y != null) {
result += this.propertyTypes[i].getHashCode(y, factory);
}
}
return result;
}
这是预期的行为吗?我被引导相信您定义自己的equals()/hashCode()
的原因之一是JPA将决定是创建新实体还是将其合并到现有实体。如果它们不被用于此,它们有什么用呢?