次のコードを使用しようとしています
Query query;
query = entityManager.createQuery("SELECT g.name FROM group g INNER JOIN user_group ug INNER JOIN user u ON u.id = ug.userid AND ug.groupoid = g.id AND u.name = ?1 AND u.password = ?2");
query.setParameter(1, user.getName());
query.setParameter(2, user.getPassword());
Object result = (Object) query.getSingleResult();
String name = (String) result;
コードを実行すると、次の例外が発生します
Caused by: Exception [EclipseLink-8023] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Syntax error parsing the query [SELECT g.name FROM group g INNER JOIN user_group ug INNER JOIN user u ON u.id = ug.userid AND ug.groupoid = g.id AND u.name = ?1 AND u.password = ?2].
Internal Exception: org.eclipse.persistence.internal.libraries.antlr.runtime.EarlyExitException
at org.eclipse.persistence.exceptions.JPQLException.syntaxError(JPQLException.java:352)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.handleRecognitionException(JPQLParser.java:354)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.addError(JPQLParser.java:246)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.reportError(JPQLParser.java:363)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.joinAssociationPathExpression(JPQLParser.java:2746)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.join(JPQLParser.java:2364)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.identificationVariableDeclaration(JPQLParser.java:2179)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.fromClause(JPQLParser.java:2043)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.selectStatement(JPQLParser.java:364)
at org.eclipse.persistence.internal.jpa.parsing.jpql.antlr.JPQLParser.document(JPQLParser.java:281)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.parse(JPQLParser.java:134)
at org.eclipse.persistence.internal.jpa.parsing.jpql.JPQLParser.buildParseTree(JPQLParser.java:95)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:215)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:190)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:142)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:126)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1475)
... 71 more
mysql コンソールで SQL コードを実行すると、機能します。JPQLを正しく実行していないと思います。
正しいクエリの作成方法を知っている人はいますか?
編集:私のグループクラスは次のとおりです。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package model.entities;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* @author Felipe
*/
@Entity
@Table(name = "grupo")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Grupo.findAll", query = "SELECT g FROM Grupo g"),
@NamedQuery(name = "Grupo.findById", query = "SELECT g FROM Grupo g WHERE g.id = :id"),
@NamedQuery(name = "Grupo.findByNome", query = "SELECT g FROM Grupo g WHERE g.nome = :nome")})
public class Grupo implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "Id")
private Integer id;
@Size(max = 255)
@Column(name = "Nome")
private String nome;
@JoinTable(name = "usuario_grupo", joinColumns = {
@JoinColumn(name = "GrupoID", referencedColumnName = "Id")}, inverseJoinColumns = {
@JoinColumn(name = "UsuarioID", referencedColumnName = "Id")})
@ManyToMany(fetch = FetchType.EAGER)
private Collection<Usuario> usuarioCollection;
public Grupo() {
}
public Grupo(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
@XmlTransient
public Collection<Usuario> getUsuarioCollection() {
return usuarioCollection;
}
public void setUsuarioCollection(Collection<Usuario> usuarioCollection) {
this.usuarioCollection = usuarioCollection;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Grupo)) {
return false;
}
Grupo other = (Grupo) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "model.entities.Grupo[ id=" + id + " ]";
}
}
そして、私の User クラスは次のとおりです。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package model.entities;
import java.io.Serializable;
import java.util.Collection;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
/**
*
* @author Felipe
*/
@Entity
@Table(name = "usuario")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Usuario.findAll", query = "SELECT u FROM Usuario u"),
@NamedQuery(name = "Usuario.findById", query = "SELECT u FROM Usuario u WHERE u.id = :id"),
@NamedQuery(name = "Usuario.findBySenha", query = "SELECT u FROM Usuario u WHERE u.senha = :senha"),
@NamedQuery(name = "Usuario.findByNome", query = "SELECT u FROM Usuario u WHERE u.nome = :nome")})
public class Usuario implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "Id")
private Integer id;
@Size(max = 255)
@Column(name = "Senha")
private String senha;
@Size(max = 255)
@Column(name = "Nome")
private String nome;
@ManyToMany(mappedBy = "usuarioCollection", fetch = FetchType.EAGER)
private Collection<Grupo> grupoCollection;
public Usuario() {
}
public Usuario(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSenha() {
return senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
@XmlTransient
public Collection<Grupo> getGrupoCollection() {
return grupoCollection;
}
public void setGrupoCollection(Collection<Grupo> grupoCollection) {
this.grupoCollection = grupoCollection;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Usuario)) {
return false;
}
Usuario other = (Usuario) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "model.entities.Usuario[ id=" + id + " ]";
}
}
注: これらのクラスは、Netbeans によって生成されました。注 2: 一部の名前はポルトガル語です。