我正在构建一个JSF应用程序,并希望在页面上列出一些实体。我有三个实体:Panel
,PanelDefinition
和Protein
。一个页面是一个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
}
答案 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