I am using SEAM with JPA (implemented as a Seam Managed Persistance Context), in my backing bean I load a collection of entities (ArrayList) into the backing bean.
If a different user modifies one of the entities in a different session I want these changes to be propagated to the collection in my session, I have a method refreshList()
and have tried the following...
@Override
public List<ItemStatus> refreshList(){
itemList = itemStatusDAO.getCurrentStatus();
}
With the following query
@SuppressWarnings("unchecked")
@Override
public List<ItemStatus> getCurrentStatus(){
String s = "SELECT DISTINCT iS FROM ItemStatus iS ";
s+="ORDER BY iS.dateCreated ASC";
Query q = this.getEntityManager().createQuery(s);
return q.getResultList();
}
Re-executing the query, this just returns the same data I already have (I assume it is using the 1st level cache rather than hitting the database)
@Override
public List<ItemStatus> refreshList(){
itemStatusDAO.refresh(itemList)
}
Calling entityManager.refresh()
, this should refresh from the database however I get a javax.ejb.EJBTransactionRolledbackException: Entity not managed
exception when I use this, normally I would use entityManager.findById(entity.getId)
before calling .refresh() to ensure it is attached to the PC but as I am refreshing a collection of entities I cant do that.
It seems like quite a simple problem, I cant believe there is no way to force JPA/hibernate to bypass the cache and hit the database?!
UPDATE TEST CASE:
I am using two different browsers (1 and 2) to load the same web page, I make a modification in 1 which updates a boolean attribute in one of the ItemStatus entities, the view is refreshed for 1 to display the updated attribute, I check the database via PGAdmin and the row has been updated. I then press refresh in Browser 2 and the attribute has not been updated
I tried using the following method to merge all entities before calling .refresh, but the entities were still not updated from the database.
@Override
public void mergeCollectionIntoEntityManager(List<T> entityCollection){
for(T entity: entityCollection){
if(!this.getEntityManager().contains(entity)){
this.getEntityManager().refresh(this.getEntityManager().merge(entity));
}
}
}