SEAMとJPA(Seam Managed Persistance Contextとして実装)を使用しています。バッキングBeanで、エンティティのコレクション(ArrayList)をバッキングBeanにロードします。
別のユーザーが別のセッションのエンティティの1つを変更した場合、これらの変更をセッションのコレクションに伝達したいのですが、メソッドrefreshList()
があり、次のことを試しました...
@Override
public List<ItemStatus> refreshList(){
itemList = itemStatusDAO.getCurrentStatus();
}
次のクエリで
@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();
}
クエリを再実行すると、これは私がすでに持っているのと同じデータを返すだけです(データベースにアクセスするのではなく、第1レベルのキャッシュを使用していると思います)
@Override
public List<ItemStatus> refreshList(){
itemStatusDAO.refresh(itemList)
}
を呼び出すentityManager.refresh()
と、これはデータベースから更新されますが、javax.ejb.EJBTransactionRolledbackException: Entity not managed
これを使用すると例外が発生します。通常は、entityManager.findById(entity.getId)
.refresh()を呼び出す前に使用して、PCに接続されていることを確認しますが、エンティティのコレクションを更新しているため、これを行うことはできません。
非常に単純な問題のようです。JPA/hibernateにキャッシュをバイパスしてデータベースにアクセスさせる方法がないとは信じられません。
テストケースの更新:
2つの異なるブラウザ(1と2)を使用して同じWebページをロードしています。1で変更を加えて、ItemStatusエンティティの1つでブール属性を更新し、ビューを1に更新して、更新された属性を表示します。チェックします。 PGAdminを介したデータベースと行が更新されました。次に、ブラウザ2で更新を押しましたが、属性が更新されていません
.refreshを呼び出す前に、次の方法を使用してすべてのエンティティをマージしようとしましたが、エンティティはデータベースからまだ更新されていません。
@Override
public void mergeCollectionIntoEntityManager(List<T> entityCollection){
for(T entity: entityCollection){
if(!this.getEntityManager().contains(entity)){
this.getEntityManager().refresh(this.getEntityManager().merge(entity));
}
}
}