How to correctly implement an Idempotent Insert when using Hibernate?

Multi tool use


How to correctly implement an Idempotent Insert when using Hibernate?
I have this method in a Data Access Object, whose intent is to provide an Idempotent Insert (duplicate inserts of same object should be ignored):
public void persistAll(Stream<AddressKeyEntity> keySet) {
final Map<AddressKeyEntity,AddressKeyEntity> addressKeyCache = listKeys().stream().collect(Collectors.toMap(k->k, k->k));
final Session currentSession = sessionFactory.getCurrentSession();
keySet.forEach(addressKey -> {
addressKeyCache.computeIfAbsent(addressKey, ak -> {
currentSession.save(addressKey);
return addressKey;
});
});
}
This is very verbose, and potentially inefficient (depending on db size). Is there a more succinct implementation which naturally would be less buggy?
UPDATE
I decided to completely rewrite the method using a different approach, which unfortunately is much slower and subject to race conditions in a multi-threaded app:
public void persistAll(Stream<AddressKeyEntity> keySet) {
final Session currentSession = sessionFactory.getCurrentSession();
keySet.filter(ak -> fetch(ak) == null).forEach(currentSession::save);
}
public AddressKeyEntity fetch(AddressKeyEntity addressKeyEntity) {
if(addressKeyEntity.isTransient()) {
return sessionFactory.getCurrentSession().byNaturalId(AddressKeyEntity.class)
.using(AddressKeyEntity_.ADDRESS, addressKeyEntity.getAddress())
.using(AddressKeyEntity_.CITY, addressKeyEntity.getCity())
.using(AddressKeyEntity_.STATE, addressKeyEntity.getState())
.using(AddressKeyEntity_.ZIP, addressKeyEntity.getZip())
.using(AddressKeyEntity_.APN, addressKeyEntity.getApn())
.load();
}
else
return addressKeyEntity;
}
What is the ultimate idiomatic way to implement an Idempotent Insert in Hibernate?
addressKeyCache
Set
It's a workaround for missing
computeIfAbsent
in Set
– Alex R
yesterday
computeIfAbsent
Set
Are you updating it anywhere? If not, then you dont need
computeIfAbsent
but simple contains
will do– Antoniossss
yesterday
computeIfAbsent
contains
Besides, why cant you just save and catch
rg.h2.jdbc.JdbcSQLException: Unique index or primary key violation
? Why do you want to do the RDBMS' job?– Antoniossss
yesterday
rg.h2.jdbc.JdbcSQLException: Unique index or primary key violation
The
contains()
won't work well under multi-threading (which has been removed for now just to achieve MVCE)– Alex R
yesterday
contains()
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
WTF is that map
addressKeyCache
?? That effectively result inSet
– Antoniossss
yesterday