插入了重复的可嵌入对象

时间:2018-05-16 10:42:21

标签: java hibernate spring-data-jpa

我有Entity包含Embeddable个对象的集合,如下所示:

@Entity
@EntityListeners(AuditingEntityListener.class)
@Table(name = "as")
public class A {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ElementCollection
    private Set<B> bs;

    public B getB(String name) {
        for(B b : bs)
            if(b.getName().equals(name))
                return b;
        return null;
    }

    public void addB(B b) {
        if(!bs.add(b))
        throw new IllegalArgumentException("Duplicate ......");
    }

    ....
}

@Embeddable
public class B {

    @Column(nullable = false)
    private String name;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Date creationTimestamp;

}

我正在使用Spring Data加载和保存我的实体,如下所示:

Optional<A> a = aRepository.findById(aId);

B b = a.getB(...);
if(b == null) {
    b = new B(...);
    a.addB(b);
}

aRepository.save(a);

上面的代码是使用@Transactional注释的方法。

当方法返回时,我可以在数据库中看到3个重复的可嵌入对象,而不是一个。

有什么想法吗?

修改

经过长时间的调试,我可以确认Hibernate只为我添加的单个实例插入一行。但是,当我从我的REST控制器返回创建的对象时,在某些时候,Jackson对象映射器在将对象发送回客户端之前序列化我的对象,这里发生了剩下的两个INSERT ......我以前从未见过它。 ..任何帮助将不胜感激

更多信息:

当SessionRepository提交会话更改时,最后2个INSERT完成 - 我确切地说我使用了Spring Session。如果这可以帮助......

1 个答案:

答案 0 :(得分:0)

问题发生在bs.add(b)Set添加一个对象将检查该对象是否存在于集合中。但在您的情况下,由于b,对象creationTimestamp将始终与现有对象不同。 creationTimestamp与现有对象不同。因为你是新对象,所以时间将是当前的数据时间。因此bs.add(b)始终为true

尝试删除creationTimestamp并重新运行代码以验证此操作。

您需要覆盖B

的equals()和hashCode()