Я создаю новый сервис с целью идемпотентного потребления событий Kafka и сохранения данных в новой базе данных PostgreSQL.
Событие предоставит данные, которые будут использованы в составном ключе:
@Embeddable
public class MyCompositeKey implements Serializable {
@Column(name="field1", nullable = false)
private UUID field1;
@Column(name="field2", nullable = false)
private UUID field2;
@Column(name="field3", nullable = false)
private UUID field3;
... boilerplate Constructors/getters ...
И сущность будет ссылаться на нее через @EmbeddedId
:
@Entity
@Table
public class MyEntity implements Serializable {
@EmbeddedId private MyCompositeKey myCompositeKey;
... Columns/Constructors/getters ...
Когда событие используется, я хочу, чтобы spring-data-jpa
был достаточно умен, чтобы знать, заменяем ли мы данные из существующего MyEntity или создаем новую строку.
Логика считалась достаточно безопасной, чтобы использовать метод CrudRepository#save
, прежде чем исследовать ожидание логики в этом методе:
@Transactional
public <S extends T> S save(S entity) {
if (this.entityInformation.isNew(entity)) {
this.em.persist(entity);
return entity;
} else {
return this.em.merge(entity);
}
}
Я дошел до того, что транзакции кажутся завершенными, но в таблице не сохраняются никакие записи.
Я подтвердил с помощью отладки, что вызов #save
ответвляется к логике return this.em.merge(entity)
, упомянутой выше.
Я нашел только один, возможно, полезный пост в блоге [1] для подобного сценария, и я заблудился о том, куда идти дальше после того, как он, похоже, не решил проблему.
Единственный другой вариант, который я могу предвидеть, - вручную выполнить потенциальное выполнение трех запросов:
findById
- , если существует,
delete
save
Компоненты
- spring-boot-starter 2.0.6
- spring-boot-starter-data-jpa 2.0.6
- hibernate 5.2.x
Ссылки
[1] https://jivimberg.io/blog/2018/11/05/using-uuid-on-spring-data-jpa-entities/