【问题标题】:JPQL: Postgres entity is not recognized with TABLE_PER_CLASS inheritanceJPQL:无法使用 TABLE_PER_CLASS 继承识别 Postgres 实体
【发布时间】:2015-09-03 20:18:03
【问题描述】:

我有一个如下所示的课程:

@Entity(name="DashboardWidget")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class DashboardWidget 
{
    public enum Type {USER_COUNT, ...};

    @Column(name="COMPANY_ID")
    protected Long companyId;

    @Enumerated(EnumType.STRING)
    protected Type type;

    ...

这个实体后面没有桌子。这些表与每个子类实体一起存在。这些类如下所示:

@Entity
@Table(name = "WIDGET_USER_COUNT")
public class UserCountWidget extends DashboardWidget 
{
    ...

使用 Spring Data JPA,我的存储库中有以下内容:

List<DashboardWidget> findByCompanyId(Long companyId);

这很好用,并且 List 有不同子具体类的实例。然后我有一个用例,我只需要Type 枚举中的Set,这样我就不必加载完整的实体。所以,我将它添加到我的 Spring Data 存储库中:

@Query("SELECT w.type FROM DashboardWidget w WHERE w.companyId = :companyId")
Set<DashboardWidget.Type> getWidgetTypes(@Param("companyId") Long companyId);

但是,当它被调用时,我收到以下错误:

Internal Exception: org.postgresql.util.PSQLException: ERROR: relation "dashboardwidget" does not exist
  Position: 18
Error Code: 0
Call: SELECT TYPE FROM DASHBOARDWIDGET WHERE (COMPANY_ID = ?)
    bind => [8888810010000000000]
Query: ReportQuery(referenceClass=DashboardWidget sql="SELECT TYPE FROM DASHBOARDWIDGET WHERE (COMPANY_ID = ?)")
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:682)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:2002)
    at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
    at org.eclipse.persistence.sessions.server.ClientSession.executeCall(ClientSession.java:250)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
    at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
    at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2738)
    at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllReportQueryRows(ExpressionQueryMechanism.java:2675)
    at org.eclipse.persistence.queries.ReportQuery.executeDatabaseQuery(ReportQuery.java:848)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1804)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1786)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1751)
    at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
    ... 99 more
Caused by: org.postgresql.util.PSQLException: ERROR: relation "dashboardwidget" does not exist
  Position: 18
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2157)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1886)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:555)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:417)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:302)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
    at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:83)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:1007)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:642)
    ... 119 more

我不太了解 JPQL,不知道这是否与我的查询有关,或者 Spring Data 是否正在做某种魔术来使 findByCompanyId 方法起作用。我可以做些什么来使getWidgetTypes 方法起作用吗?

【问题讨论】:

  • 看起来像一个错误,因为 Eclipselink 正在查询 DashboardWidget 描述符。您使用的是哪个 EclipseLink 版本?
  • @Chris Eclipselink 2.5.2 版

标签: java postgresql jpa spring-data-jpa jpql


【解决方案1】:

您似乎创建了带有引号的表,但试图在没有引号的情况下对其进行查询。 Postgres 是case-insensitive for unquoted identifiers。如果是这种情况,您需要考虑引号并使用 @Entity(name="\"DashboardWidget\"")@NamedQueries 之类的东西,以免混淆大小写。

一般来说,好的做法是不要对 psql 中的表使用引号,除非您有正当理由。

【讨论】:

  • 我没有带引号的表格。没有 DashboardWidget 表。这就是它爆炸的原因。它试图查询一个不存在的表。我的问题是如何编写 JPQL,以便它知道查询子类/实体使用的表。 Spring Data 以某种方式使其工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-03
  • 2017-10-30
  • 2021-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多