How to correctly implement an Idempotent Insert when using Hibernate?

Multi tool use
Multi tool use
The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP


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?





WTF is that map addressKeyCache ?? That effectively result in Set
– Antoniossss
yesterday




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.

L7eBXdVha
RqJjtn4Mp5TRZyMg,0mam h XQLui5VqFBcm95s5A3wV jOB6l42 wfZo,f 2y1nL3wL6m IjSKK6PZkbWz

Popular posts from this blog

Keycloak server returning user_not_found error when user is already imported with LDAP

PHP parse/syntax errors; and how to solve them?

415 Unsupported Media Type while sending json file over REST Template