Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate重新创建以前在合并时删除的实体()-如何避免?_Hibernate_Jpa_Spring Data Jpa - Fatal编程技术网

Hibernate重新创建以前在合并时删除的实体()-如何避免?

Hibernate重新创建以前在合并时删除的实体()-如何避免?,hibernate,jpa,spring-data-jpa,Hibernate,Jpa,Spring Data Jpa,当我在一个事务中删除一个实体,然后在另一个事务中再次合并该实体时,Hibernate将在数据库中创建具有新ID的实体 我以为它会抛出一个非法的ArgumentException 环境:Hibernate5.2.x和SpringData2.0.x 问题: 如何让EntityManager抛出异常 如果不可能,最好的解决方法是什么?现在,我在save()完成后检查实体的ID:如果它发生了更改,则该实体已被重新创建 重现问题的代码-此处两个线程被导致相同情况的刷新/清除替换: // given..

当我在一个事务中删除一个实体,然后在另一个事务中再次合并该实体时,Hibernate将在数据库中创建具有新ID的实体

我以为它会抛出一个非法的ArgumentException

环境:Hibernate5.2.x和SpringData2.0.x

问题:

  • 如何让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。您是获得新序列还是与旧序列一起保存?