When my Java application was running on Spring Boot 2.6.2, the entities for which Export/Import features applied were using the following custom id generator:
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentityGenerator;
import java.io.Serializable;
public class CustomIdGenerator extends IdentityGenerator {
@Override
public Serializable generate(SharedSessionContractImplementor session, Object entity) {
Serializable id = session.getEntityPersister(null, entity)
.getClassMetadata().getIdentifier(entity, session);
return id != null ? id : super.generate(session, entity);
}
}
so that, when an Id was provided in the CSV file, the import was producing the very same entity in the database, with the very same Id.
In particular, I was able to save and restore the whole table by doing these actions in the following order:
- Export (to save as CSV)
- Import an empty CSV file (clears the table)
- Import the saved CSV file Result: after these 3 operations, the database content was exactly the same as before.
Now that I have migrated my application to Spring Boot 3.3.1, this doesn't work anymore. I was forced to dispose of CustomIdGenerator because this implementation is no more compatible with Spring Boot 3.3.1 (because of its Hibernate dependency). I tried to obtain a similar CustomIdGenerator the new way, but in vain after several attempts and a couple of evenings trying to achieve that...
To summarize: I need the Ids of my entity to be auto-generated (like with GenerationType.IDENTITY) when they are provided without Id, but I need the Ids to be strictly identical to those provided in the CSV file in case of an import action.
Any known way to do that with success?
--
For example, I tried to implement a CustomIdGenerator this way (Spring Boot 3.3.1):
public class NewCustomIdGenerator implements IdentifierGenerator {
@Override
public Object generate (SharedSessionContractImplementor session, Object entity) {
var id = session.getEntityPersister(entity.getClass().toString(), entity).getIdentifier(entity, session);
if (id != null) {
return id;
}
//var res = super.generate(session, entity); // doesn't work
var res = 0L; // doesn't work (here I'd like the auto-generation to take over)
return res;
}
I also tried to extend IncrementGenerator or TableGenerator... in vain.
Any idea that works?
EntityManager.persistyou should tryEntityManager.merge. This should in my understanding preserve the id of the entity that is being merged exactly as you demand.EntityManager.persitorEntityManager.merge, I'm usingJpaRepository.saveAll- I'll check again ifAbstractEntityInformation.isNewreturns true or false when it should and ifem.persistorem.mergeis called. Then I'll come back to you.EntityManager.mergethat's called. Right after this, I see, with Spring Boot 3.3.1, that the Ids of the new entities are not those provided by the CSV file, contrary to the behaviour I had with Spring Boot 2.6.2.@PrePersistand@PostPersistwith Spring Boot 3.3.1. It was not changed with Spring Boot 2.6.2.