Hibernate重新创建以前在合并时删除的实体()-如何避免?
当我在一个事务中删除一个实体,然后在另一个事务中再次合并该实体时,Hibernate将在数据库中创建具有新ID的实体 我以为它会抛出一个非法的ArgumentException 环境:Hibernate5.2.x和SpringData2.0.x 问题:Hibernate重新创建以前在合并时删除的实体()-如何避免?,hibernate,jpa,spring-data-jpa,Hibernate,Jpa,Spring Data Jpa,当我在一个事务中删除一个实体,然后在另一个事务中再次合并该实体时,Hibernate将在数据库中创建具有新ID的实体 我以为它会抛出一个非法的ArgumentException 环境:Hibernate5.2.x和SpringData2.0.x 问题: 如何让EntityManager抛出异常 如果不可能,最好的解决方法是什么?现在,我在save()完成后检查实体的ID:如果它发生了更改,则该实体已被重新创建 重现问题的代码-此处两个线程被导致相同情况的刷新/清除替换: // given..
- 如何让EntityManager抛出异常
- 如果不可能,最好的解决方法是什么?现在,我在save()完成后检查实体的ID:如果它发生了更改,则该实体已被重新创建
// given...
MyEntity entity = jpaRepository.findByXXX("0001");
jpaRepository.delete(entity);
em.flush();
em.clear();
// when...
Throwable thrown = catchThrowable(() -> jpaRepository.save(entity));
// then...
// FAILs as no exception was thrown, instead entity with new ID was returned
assertThat(thrown).isInstanceOf(IllegalArgumentException.class);
问题似乎根源于它在数据库中找不到实体时会生成一个新ID的地方
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
EntityEntry entry = persistenceContext.getEntry( entity );
if ( entry == null ) {
EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
Serializable id = persister.getIdentifier( entity, source );
if ( id != null ) {
final EntityKey key = source.generateEntityKey( id, persister );
final Object managedEntity = persistenceContext.getEntity( key );
entry = persistenceContext.getEntry( managedEntity );
if ( entry != null ) {
// we have specialized case of a detached entity from the
// perspective of the merge operation. Specifically, we
// have an incoming entity instance which has a corresponding
// entry in the current persistence context, but registered
// under a different entity instance
entityState = EntityState.DETACHED;
}
}
}
您正在调用em.clear();这将清除PersistenceContext Hibernate如何知道您删除了实体?加上什么是ID生成策略?@SimonMartinelli-Hibernates使用
persistenceContext.getEntry(entity)
进入数据库,并知道该实体不存在。您使用哪种ID生成策略?@SimonMartinelli-我使用的是标准hibernate序列生成器@GeneratedValue(strategy=GenerationType.SEQUENCE)
Ok。您是获得新序列还是与旧序列一起保存?