My user
DB table looks like this:
CREATE TABLE user (
username VARCHAR(32) PRIMARY KEY,
first_name VARCHAR(256) NOT NULL,
last_name
One can perhaps use existsById(ID primaryKey) to test it, if userRepository extends CrudRepository:
if(userRepository.existsById(username)){
//Throw your Exception
} else {
this.userRepository.save(user);
}
see https://docs.spring.io/spring-data/jpa/docs/current/reference/html/
Instead of this.userRepository.save(user) , can you try this.userRepository.saveAndFlush(user)
My best guess is, it will make your entity detached and as per the JPA documentation, it states an EntityExistsException is thrown by the persist method when the object passed in is a detached entity. Or any other PersistenceException when the persistence context is flushed or the transaction is committed.
When using the default configuration, and using CrudRepository#save()
or JpaRepository#save()
it will delegate to the EntityManager
to use either persists()
if it is a new entity, or merge()
if it is not.
The strategy followed to detect the entity state, new or not, to use the appropiate method, when using the default configuration is as follows:
null
, then it is a new entity, otherwise is not.Persistable
the detection will be delegated to the isNew()
method implemented by the entity.EntityInformation
, but further customizations are needed.source
So in your case, as you are using the username as ID
, and it isn't null, the Repository call ends up delegating to EntityManager.merge()
instead of persist()
. So there are two possible solutions:
ID
property, set it to null, and use any auto-generation method, orPersistable
and use the isNew()
method, to determine if it is a new entity or not.If for some reason, you don't want to modify your entities, you can also change the behaviour modifying the flush mode configuration. By default, in spring data jpa, hibernate flush mode is set to AUTO. What you want to do is to change it to COMMIT, and the property to change it is org.hibernate.flushMode
. You can modify this configuration by overriding a EntityManagerFactoryBean
in a @Configuration
class.
And if you don't want to mess the configuration of the EntityManager, you can use the JpaRepository#flush()
or JpaRepository#saveAndFlush()
methods, to commit the pending changes to the database.