【问题标题】:Detached entity issue using Hibernate with mutiny使用带有兵变的 Hibernate 的分离实体问题
【发布时间】:2021-12-29 20:27:06
【问题描述】:

作为集成测试的一部分,我使用以下代码查询实体,然后将其从底层数据存储中删除:

Country country = countryRepository.findById("CH").await().indefinitely();
countryRepository.remove(country).await().indefinitely();

相应的实现由抽象存储库类给出:

public abstract class AbstractRepository<Entity extends AbstractEntity,Id> implements Repository<Entity, Id> {

    @Inject
    private Mutiny.SessionFactory sessionFactory;
    private final Class<Entity> _class;

    public AbstractRepository(Class<Entity> _class){
        this._class = _class;
    }

    @Override
    public Uni<List<Entity>> findAll() {
        return sessionFactory.withSession(s->s.createQuery("SELECT e from "+ _class.getName()+" e", _class)
                .getResultList())
                .onItem().invoke(l-> l.forEach(AbstractEntity::markAsPersistent));
    }

    @Override
    public Uni<Entity> findById(Id id) {
        return sessionFactory.withSession(s->s.find(_class, id));
    }

    @Override
    public Uni<Entity> add(Entity entity) {
        if(entity.isPersistent()){
            return sessionFactory.withSession(s ->s.merge(entity));
        }else{
            entity.markAsPersistent();
            return sessionFactory.withSession(s ->s.persist(entity).chain(s::flush).replaceWith(entity));
        }
    }

    @Override
    public Uni<Void> remove(Entity entity) {
        return sessionFactory.withSession(s -> s.remove(entity));
    }
}

使用休眠/mutiny 可以正确检索实体,但是在尝试删除它时,remove 方法会触发异常:

javax.persistence.PersistenceException: org.hibernate.HibernateException: java.util.concurrent.CompletionException: java.lang.IllegalArgumentException: unmanaged instance passed to remove()
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.reactive.session.impl.ReactiveExceptionConverter.convert(ReactiveExceptionConverter.java:31)

在编辑我的问题时,刚刚意识到我正在使用两个不相交的会话(一个用于检索实体,另一个用于删除实体),这可能是我收到错误的原因。

但不确定我应该如何重构代码以使其正常工作。

【问题讨论】:

    标签: hibernate mutiny hibernate-reactive


    【解决方案1】:

    好的,事实证明我的问题有一个相对简单的解决方案。我需要做的就是首先使用 SessionFactory.find() 检索实体,然后使用 remove 链接:

        @Override
        public Uni<Void> remove(Entity entity) {
            return sessionFactory.withTransaction((s,t) -> s.find(_class, entity.getId()).chain(s::remove));
        }
    

    这可能不是最好的方法,尤其是当实体有很多预先加载的关联时。但是这个问题确实被触发了,因为我试图删除一个实体,该实体是在另一个会话中检索到的

    编辑 实际上,没有默认的预先加载关联,如docs中所述

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2012-08-21
      • 2018-07-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多