Как сделать обновление базы данных при методе fini sh в JPA - PullRequest
0 голосов
/ 16 июня 2020

Существует бизнес-лог c, где сначала вызывается один метод, сохраняющий сущность. Следующий метод извлекает данные из БД. когда вызывается второй метод, этот список результатов содержит предыдущее значение объекта, поскольку объект еще не сохранен. Есть ли способ синхронизировать этот бизнес-журнал c, чтобы второй метод, вызываемый после завершения транзакции первого метода, был завершен.

Используется EntityManager em для сохранения данных, здесь код

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class DemoService { 

    @PersistenceContext(unitName = "primary")
    private EntityManager em;

    public  Demo createOrUpdate (Demo obj) {

      //This function is to update enity
      createOrUpdate_(obj);

      //In this function need to get updated enities(latest saved)
      fetchResultSet();
      return obj;  
    }


    @Transactional
    public  Demo createOrUpdate_ (Demo obj) {
      em.merge(obj);
      return obj;  
    }

} 



1 Ответ

0 голосов
/ 14 августа 2020

Когда вы вызываете свой метод fetchResultSet (), фиксация не происходит - это происходит, когда вызывающий метод, в вашем случае createOrUpdate (Demo obj), завершается без каких-либо исключений.

Вы также возвращаетесь а не объединенный объект в вашем методе createOrUpdate_ (Demo). Обратите внимание, что для каждого API EntityManager # merge (T) имеет в качестве возвращаемого объекта управляемый объект, поэтому ваш указатель obj может быть связан с вашим исходным объектом. Кстати, в идеале вы не должны использовать entityManager непосредственно в своих классах обслуживания.

Я предлагаю вам изменить свой код на что-то вроде этого (не полный, с использованием EJB, а не CDI, но я думаю, что это показывает достаточно). Сначала базовый менеджер.

public abstract BaseManager<T> {

    @PersistenceContext
    private EntityManager em;
    
    protected abstract Class<T> getEntityClass();

    @TransactionAttribute
    public T createOrUpdate(T e) {
        if (em.contains(e)) {
            em.persist(e);
            return e;
        } else {
            return em.merge(e);
        }
    }

    public List<T> findAll() {
        String q = String.format("SELECT o FROM %s AS o", getEntityClass().toCanonicalName()0;
        return em.createQuery(q, getEntityClass()).getResultList();
    }
}

Затем менеджер сущностей:

@Stateless
public DemoManager extends BaseManager<Demo> {

    protected Class<Demo> getEntityClass() {
        return Demo.class;
    }
}

Теперь ваш класс обслуживания:

@Stateless
public ExampleService {

    @EJB
    private DemoManager demoManager;

    public Set<Demo> addDemoToSet(Demo demo) {
        demoManager.createOrUpdate(demo);
        return new HashSet<>(demoManager.findAll());
    }
}

При таком подходе вызов demoManager.createOrUpdate будет транзакционным, и ваш последующий вызов findAll получит все значения (если это ваша цель).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...