【问题标题】:EclipseLink firing find query randomly before getting resultset from createNativeQueryEclipseLink 在从 createNativeQuery 获取结果集之前随机触发查找查询
【发布时间】:2016-11-26 13:03:24
【问题描述】:

EclipseLink 的奇怪行为(Eclipse Persistence Services - 2.1.1.v20100817-r8050),我有一个错误(虚拟/不是 DB 中的实际表)实体类来保存从 createNativeQuery(query, entity.班级) @实体 公共类 VirtualTable 实现 Serializable { private static final long serialVersionUID = 1L;

@Id
@Column(name = "ROW")
private Integer row;

@Column(name = "ABC")
private String abc= null

@Column(name = "XYZ")
private String xyz= null

以下是我获取结果集的代码 我已将 entityClass 设置为 VirtualTable.class

/**
 * Get a list of entity objects by a native query.
 * 
 * @param nativeQueryString the query.
 * @param qryParamList the parameters for the query. Must be in the  same    order as listed in the query.
 * @param entityClass the Class of the entity object. The entityClass    field must be mapped to the 
 *        column names from the query result set.
 * @return a list of entity object of class entityClass
 */
@SuppressWarnings("rawtypes")
public static List getObjectListByNativeQuery(String nativeQueryString,
        List<Object> qryParamList, Class entityClass) {
    EntityManager em =  ReportRepository.getEntityManager(SqlConstants.PERSISTENCE_UNIT_NAME_PODR_RPT  );

    //populate the parameter list
    logger.info("em test inside query"+ em.hashCode()   +"                  "+nativeQueryString + ", with ref class: " + entityClass.getName());
    Query query = em.createNativeQuery(nativeQueryString, entityClass);

    if(qryParamList != null && qryParamList.size() > 0) {
        for(int i=0; i< qryParamList.size(); i++) {
            Object param = qryParamList.get(i);
            //the native query parameters must start with 1 
            query.setParameter(i+1, param);
        }
    }
    List resultList = query.getResultList();
            return resultList;
}enter code here

在返回结果集之前,JPA 尝试自行触发查找查询,由于该表不在 DB 中,因此会抛出未找到表。 我在 persistence.xml 中使用 SOFT 缓存,除了它是一个简单的 JPA 实现。 请让我知道如何避免 JPA 对此特定实体类进行此查询并定义它不是实际的 DB 表。我想避免手动映射,我不会在任何地方保存这个虚拟表,只是获取结果集并写入 excelsheet

错误日志如下

  [7/21/16 2:46:43:455 EDT] 0007f794 SystemOut     O 2016-07-21   02:46:43.455 [WARN]     org.eclipse.persistence.session.podr02_user=PODRRPT.internalLog:588@PODRSchedWorkManager.Alarm Pool : 12  -  Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

Error Code: 942
Call: SELECT ROW, ABC, XYZ FROM VIRTUALTABLE WHERE (ROW = ?)
bind => [79]
Query: ReadObjectQuery(referenceClass=VirtualTable )

[7/21/16 2:46:43:455 EDT] 0007f794 SystemOut     O 2016-07-21   02:46:43.455   [ERROR]   com.bmo.cm.common.framework.service.AbstReportFileGenerator.generateReportFil    e:88@PODRSchedWorkManager.Alarm Pool : 12  - Exception   [EclipseLink-4002] (Eclipse Persistence Services - 2.1.1.v20100817-r8050): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist

Error Code: 942
Call: SELECT ROW, ABC, XYZ FROM VIRTUALTABLE WHERE (ROW = ?)
bind => [79]
Query: ReadObjectQuery(referenceClass=VirtualTable )

【问题讨论】:

  • 显示堆栈跟踪,因为它将指出需要查询的位置和原因。
  • 我希望我可以,在生产中,日志只是过滤掉异常,我试图在我的本地重新创建这个场景,但它从未发生过,最终我不得不以编程方式调用 em.find(virtualentity.class , primarykey) 来复制问题

标签: java jpa eclipselink entitymanager


【解决方案1】:

您不应该为此使用实体,因为实体需要 JPA 来管理和跟踪对它们的更改,这需要对象标识和缓存。相反,如果使用 JPA 2.1,您应该使用构造函数表达式在 SqlResultSetMapping 中使用 ConstructorResult 构建 pojo

【讨论】:

  • 感谢 Chris 的 cmets,奇怪的是它随机发生,假设作业在接下来的 5 分钟间隔内尝试,它不会触发 Find 查询并且没有遇到错误。有没有办法避免这种行为
  • 是的 - 不要使用实体 :)。如果您继续使用一个实体,则没有办法在不查明其原因的情况下阻止它。我的猜测是它与缓存有关;任何需要获取实体的东西都可能导致这种类型的查找查询,例如一些使用失效的共享缓存设置。如果您还没有关闭此实体的共享缓存,您可以尝试关闭
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 2016-05-27
  • 1970-01-01
  • 2013-05-13
  • 1970-01-01
  • 2021-12-05
  • 2010-10-18
相关资源
最近更新 更多