EntityManagerFactory singleton в многопоточном - PullRequest
0 голосов
/ 08 июля 2019

У меня есть приложение (javaee / wildfly / Maven), которое работает так: Thread processA (триггер Thread processB в фоновом режиме)

Я использую EJB без сохранения состояния с @PersistenceContext, все в процессе работает нормально, моя проблема связана с processB, сущность, сохраняемая внутри processA, не обновлена ​​в processB, я полагаю, это потому, что @PersistenceContext имеет кэш-память для каждого процесса, верно?Итак, сначала я хотел найти способ «обновить» кеш, когда вызывается единственный метод, который я использовал в processB, но я не нахожу ничего, чтобы сделать это ...

Затем, после дополнительных чтений, я обнаружил,что EntityManager не является потокобезопасным, и лучше использовать @singleton с EntityManagerFactory, созданным только один раз, потому что это дорого, как здесь: https://subhadipsblog.wordpress.com/2017/09/16/correct-way-of-using-entitymanager-in-singleton-ejb/

@Singleton
public class PersistenceService
{
 @PersistenceUnit(name="somePU")
 EntityManagerFactory emf;

И создание EntityManager, как показано ниже:

public void persistenceMethod(Entity myEntity)
{
 EntityManager em = emf.createEntityManager();
 ... //Persistence operations
 em.close();
}

РЕДАКТИРОВАТЬ: Итак, я добавил это:

@Singleton
public class PersistenceService {

    @PersistenceUnit(name="MyPu")
    EntityManagerFactory emf;

    public ImportState createEntity(MyEntity myEntity) {

        EntityManager em = emf.createEntityManager();
        em.merge(myEntity);
        em.close();
        }

    public List<MyEntity> getMyEntities() {

        EntityManager em = emf.createEntityManager();
        List<MyEntity> myEntities = em.createQuery("from MyEntity as myEntity, MyEntity.class)
                .getResultList();
        em.close();
        return myEntities;
    }
}

И в моих услугах:

@EJB PersistenceService persistenceService;

Но у меня все еще есть та же проблема ...

  • ThreadA -> persistenceService.createEntity (myEntity) -> сущность создана в базе данных (org.hibernate.jpa.internal.EntityManagerFactoryImpl@3097af5)
  • ThreadB -> persistenceService.getMyEntities () ->объект, созданный ThreadA, не виден (org.hibernate.jpa.internal.EntityManagerFactoryImpl@3097af5)

РЕДАКТИРОВАТЬ создание потокаB:

ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("debut tache " + Thread.currentThread().getName());
                try {
                    System.err.println(persistenceService.getMyEntities());
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("fin tache");
            }
        });

1 Ответ

0 голосов
/ 10 июля 2019

Это, вероятно, потому что ваш поток не имеет правильной настройки контекста.Вам нужно будет скопировать контексты, которые могут быть довольно громоздкими.Если вы хотите создавать потоки, вы должны использовать утилиты Java EE Concurrency .

...