I have an application (javaee / wildfly / Maven) who works like that : Thread processA (trigger Thread processB in background)
I'm using Stateless EJB with @PersistenceContext everything is working fine in the processA, my issue is on the processB the entity persisted inside processA are not up to date in processB, I assume it's because @PersistenceContext has a cache on each process is it right ? So first I wanted to find a way to "refresh" the cache when the only method I used in processB is called, but I don't find anything to do that ...
Then after more readings I discover that the EntityManager is not thread safe and it's better to use a @singleton with an EntityManagerFactory created only once because it's expensive like here : https://subhadipsblog.wordpress.com/2017/09/16/correct-way-of-using-entitymanager-in-singleton-ejb/
@Singleton
public class PersistenceService
{
@PersistenceUnit(name="somePU")
EntityManagerFactory emf;
And creating EntityManager as below:
public void persistenceMethod(Entity myEntity)
{
EntityManager em = emf.createEntityManager();
... //Persistence operations
em.close();
}
EDIT : So I've added this :
@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;
}
}
And in my services :
@EJB PersistenceService persistenceService;
But I still have the same issue ...
- ThreadA -> persistenceService.createEntity(myEntity) -> entity is created in Database (org.hibernate.jpa.internal.EntityManagerFactoryImpl@3097af5)
- ThreadB -> persistenceService.getMyEntities() -> entity created by ThreadA is not seen (org.hibernate.jpa.internal.EntityManagerFactoryImpl@3097af5)
EDIT threadB creation :
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");
}
});