JPA命名查询变为不正确的SQL

时间:2014-02-06 14:07:10

标签: jpa jpql

我正在构建一个JSF应用程序,并希望在页面上列出一些实体。我有三个实体:PanelPanelDefinitionProtein。一个页面是一个Protein实体的详细信息页面。我想在该详细信息页面上做的一件事是列出Panel的所有Protein个实体。

为此,我在我的PanelController类(JSF托管会话范围bean)中使用了一个方法,该方法使用我的PanelService(无状态EJB)来调用命名查询Panel.byProtein。当我这样做时,我得到错误:

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '.panel_id) AND (t0.target = 5)) AND (t0.panel = t1.panel_id))' at line 1
Error Code: 1064
Call: SELECT t1.panel_id, t1.comment, t1.insert_date, t1.name, t1.panel_version, t1.status, t1.inserted_by, t1.previous_version FROM panel_definition t0, panel t1 WHERE (((t0.panel = t1.panel_id.t1.panel_id) AND (t0.target = ?)) AND (t0.panel = t1.panel_id))
    bind => [1 parameter bound]
Query: ReadAllQuery(name="Panel.byProtein" referenceClass=Panel sql="SELECT t1.panel_id, t1.comment, t1.insert_date, t1.name, t1.panel_version, t1.status, t1.inserted_by, t1.previous_version FROM panel_definition t0, panel t1 WHERE (((t0.panel = t1.panel_id.t1.panel_id) AND (t0.target = ?)) AND (t0.panel = t1.panel_id))")
    at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:340)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:679)
    at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
    at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
    at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
    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:2714)
    at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2667)
    at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:477)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1155)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1114)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:402)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1202)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1744)
    at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)

t0.panel = t1.panel_id.t1.panel_id确实看起来不合适。我怎么以及为什么得到不正确的sql?

以下是我的实体类的简化版本:

@Entity
@NamedQueries({
    @NamedQuery(name = "Panel.findAll", query = "SELECT p FROM Panel p"),
    @NamedQuery(name = "Panel.byProtein", query = "SELECT p FROM Panel p JOIN p.panelDefinition pd WHERE pd.pdId = p.panId AND pd.protein.ID = :pid"),
})
public Class Panel {
    @Id
    private Integer panId;
    @OneToMany(mappedBy = "panel")
    private List<PanelDefinition> panelDefinition;
    //More attributes + getters and setter
}

@Entity
public Class PanelDefinition {
    @Id
    private Integer pdId;
    @JoinColumn(name = "protein", referencedColumnName = "ID")
    @ManyToOne
    private Protein protein;
    @JoinColumn(name = "panel", referencedColumnName = "panId")
    @ManyToOne
    private Panel panel;
    //More attributes + getters and setter
}

@Entity
public Class Protein {
    @Id
    private Integer ID;
    //More attributes + getters and setter
}

1 个答案:

答案 0 :(得分:0)

显然我在查询中需要另一个JOIN。这个改变修正了它:

原件:

SELECT p FROM Panel p JOIN p.panelDefinition pd 
WHERE pd.pdId = p.panId AND pd.protein.ID = :pid

更新了查询:

SELECT p FROM Panel p JOIN p.panelDefinition pd 
JOIN pd.protein t 
WHERE p.panId = pd.panel.panId AND t.ID = :id