后端数据库异步变化时如何刷新JPA实体?
我有一个PostgreSQL 8.4数据库,其中包含一些表和视图,它们本质上是某些表的联接。我使用 NetBeans 7.2(如此处所述)创建了从这些视图和表派生的基于 REST 的服务,并将其部署到 Glassfish 3.1.2.2 服务器上。
还有另一个过程可以异步更新用于生成视图的某些表中的内容。我可以直接查询视图和表,并查看这些更改是否正确发生。但是,当从基于 REST 的服务中提取时,这些值与数据库中的值不同。我假设这是因为 JPA 已将数据库内容的本地副本缓存在 Glassfish 服务器上,并且 JPA 需要刷新关联的实体。
我尝试向 NetBeans 生成的 AbstractFacade 类中添加几个方法:
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
private String entityName;
private static boolean _refresh = true;
public static void refresh() { _refresh = true; }
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
this.entityName = entityClass.getSimpleName();
}
private void doRefresh() {
if (_refresh) {
EntityManager em = getEntityManager();
em.flush();
for (EntityType<?> entity : em.getMetamodel().getEntities()) {
if (entity.getName().contains(entityName)) {
try {
em.refresh(entity);
// log success
}
catch (IllegalArgumentException e) {
// log failure ... typically complains entity is not managed
}
}
}
_refresh = false;
}
}
...
}
然后,我从 NetBeans 生成的每个方法中调用。通常发生的事情是被抛出,说明一些像doRefresh()
find
IllegalArgumentsException
Can not refresh not managed object: EntityTypeImpl@28524907:MyView [ javaType: class org.my.rest.MyView descriptor: RelationalDescriptor(org.my.rest.MyView --> [DatabaseTable(my_view)]), mappings: 12].
因此,我正在寻找有关如何正确刷新与视图关联的实体的一些建议,以便它是最新的。
更新:事实证明,我对潜在问题的理解是不正确的。这与我之前发布的另一个问题有些相关,即视图没有可以用作唯一标识符的单个字段。NetBeans 要求我选择一个 ID 字段,所以我只选择了本应是多部分键的一部分。这表现为具有特定 ID 字段的所有记录都相同,即使数据库具有具有相同 ID 字段的记录,但其余部分不同。JPA没有走得更远,只是看着我告诉它是唯一标识符的东西,并简单地提取了它找到的第一条记录。
我通过添加唯一标识符字段解决了这个问题(永远无法使多部分密钥正常工作)。