SpringBoot,@ EmbeddedId等于()/ hashCode()

时间:2017-11-30 21:34:30

标签: hibernate jpa spring-boot

我有这个课程,我使用它作为@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将决定是创建新实体还是将其合并到现有实体。如果它们不被用于此,它们有什么用呢?

0 个答案:

没有答案