【发布时间】:2012-10-26 20:59:45
【问题描述】:
我有一个 PostgreSQL 8.4 数据库,其中包含一些表和视图,这些表和视图本质上是一些表的连接。我使用 NetBeans 7.2(如 here 所述)创建从这些视图和表派生的基于 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 生成的每个 find 方法调用 doRefresh()。通常发生的情况是 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].
所以我正在寻找一些关于如何正确刷新与视图关联的实体以使其保持最新的建议。
更新: 原来我对潜在问题的理解是不正确的。它与another question I posted earlier 有点相关,即视图没有可用作唯一标识符的单个字段。 NetBeans 要求我选择一个 ID 字段,所以我只选择了应该是多部分键的一部分。这表现出具有特定 ID 字段的所有记录都相同的行为,即使数据库具有具有相同 ID 字段但其余部分不同的记录。 JPA 只是查看了我告诉它的唯一标识符,并简单地提取了它找到的第一条记录。
我通过添加一个唯一标识符字段解决了这个问题(一直无法让多部分密钥正常工作)。
【问题讨论】:
-
请发布您的
persistence.xml减去任何<class/>条目。特别是二级缓存控件。 -
另外,这些也不是全部例外。会有一个原因链导致 EclipseLink 抛出 real 异常。请显示 EclipseLink 异常和(如果抛出)任何底层 PgJDBC 异常。如果您的应用程序没有输出它们,请查看 Glassfish 日志。
标签: java postgresql jpa netbeans glassfish