JPA分离实体在退出时仍然存在

时间:2016-09-21 19:45:40

标签: spring hibernate jpa spring-data spring-data-jpa

我在使用hibernate和spring-data时遇到autopersist问题。我有以下服务,我创建entityA。

@Service
public class entityAService {

    private final EntityARepository repository;

    @PersistenceContext(unitName = "entityManagerFactory")
    EntityManager entityManager;

    @Autowired
    public entityAService(EntityARepository repository) {
        this.repository = repository;
    }

    @Transactional
    public EntityA create(EntityA entityA) {
        repository.save(entityA);

        if (entityA.getRegisterExternal) {
            registerExternal();
        }

        return entityA;
    }

    private void registerExternal() {
        // we always need the entityA to be registered, however we don't want to not allow entityA creation if
        // the external register service is down. Thus we need to check for any non registered entityA's and try
        // to register them again.
        Set<EntityA> entities = repository.getEntityAWithRegisterExternalAndNotRegistered();

        ExternalRegister register = new ExternalRegister();
        for (EntityA entity: entities) {
            try {
                register.register(entity);
                entity.setRegistered(true);
                repository.save(entity);
            } catch (RegisterException e) {
                logger.warn("exception", e);
            }
        }

        return;
    }
}

我遇到麻烦的地方是“entity.setRegistered(true);”正在创建的entityA的行。当我走过这个过程之后,在“registerExternal();”之后在create方法中,我可以在db中看到最新的entityA.registered = true。但是,在create方法完成后,entityA.registered将被设置为false。

我试图在“registerExternal()”调用之前调用“entityManager.detach(entityA)和entityManager.clear(),以及在调用之后调用”entityManager.refresh(entityA),似乎没什么用。“ / p>

有没有办法将对象设置为不自动运行?

1 个答案:

答案 0 :(得分:0)

您正在从create方法返回旧实体。 Save方法返回实体的更新实例,您应该始终使用

尝试更改为此

@Transactional
public EntityA create(EntityA entityA) {
    EntityA updated = repository.save(entityA);
    if (entityA.getRegisterExternal) {
        registerExternal();
    }

    return updated;
}

但是registerExternal也在更新一些实体。这不应该是此create方法的一部分。 Create应该只处理单个创建实体(SOLID原则)。

最好将registerExternal移除到后台线程/调度程序线程。但是如果你不能这样做(但你应该这样做),那么在从create

返回之前获取最新的实体
@Transactional
public EntityA create(EntityA entityA) {
    EntityA updated = repository.save(entityA);
    if (entityA.getRegisterExternal) {
        registerExternal();
    }

    // Fetch latest using ID of EntityA
    return repository.findOne(entityA.getId());
}