Вставлены повторяющиеся встраиваемые объекты - PullRequest
0 голосов
/ 16 мая 2018

У меня есть 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 дублирующихся встраиваемых объекта в моей базе данных вместо одного.

Есть идеи?


EDIT:

После долгой отладки я могу подтвердить, что Hibernate вставляет только одну строку для одного добавляемого мной экземпляра. Однако, когда я возвращаю созданный объект из моего REST-контроллера, в какой-то момент включается преобразователь объектов Джексона, чтобы сериализовать мой объект перед отправкой его обратно клиенту, и здесь происходят две оставшиеся вставки ... Я никогда раньше этого не видел. .. любая помощь будет оценена

Дополнительная информация:

Последние 2 INSERT выполняются, когда SessionRepository фиксирует изменения сессий - я уверен, что я использую Spring Session. Если это может помочь ...

1 Ответ

0 голосов
/ 16 мая 2018

Проблема происходит здесь bs.add(b).Set добавляет объект, который будет проверять, существует ли объект в наборе.Но в вашем случае объект b всегда будет отличаться от существующего объекта из-за creationTimestamp.creationTimestamp будет отличаться от существующего объекта.Поскольку вы новый объект, время будет текущим временем данных.Так что bs.add(b) всегда будет true.

Попробуйте удалить creationTimestamp и повторите код, чтобы убедиться в этом.

Вам необходимо переопределить equals () и hashCode () для B

...