2013-12-12 14 views
5

Ich kann scheinen, um die Syntax für eine JPA-Abfrage in Richtung der Datenbank zu korrigieren. Es funktioniert perfekt mit Squirrel SQL.Korrekte Format der SQL-Abfrage in Java

Die Datenbank ist Derby und der Code verwendet JPA.

Aktualisiert mit neuer Abfrage und Fehler. Das führt mich zu der Annahme, dass etwas in der Entitätszuordnung nicht korrekt ist. Es könnte etwas in der JoinColumn-Klausel sein?

Die Namensgebung wurde korrigiert. Das verursachte das erste Problem mit der Verwendung der korrekten Entitätsnamen.

Query q = em.createQuery("select t, sum(t.result) from Serie t, Player p " + 
     " where p.id = t.player" + 
     " group by t.player"); 

Exception [EclipseLink-6076] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.QueryException 
Exception Description: Object comparisons can only be used with OneToOneMappings. Other mapping comparisons must be done through query keys or direct attribute level comparisons. 
Mapping: [org.eclipse.persistence.mappings.DirectToFieldMapping[id-->PLAYER.ID]] 
Expression: [ 
Query Key id 
    Base com.jk.hcp.Player] 
Query: ReportQuery(referenceClass=Serie jpql="select t, sum(t.result) from Serie t, Player p where p.id = t.player group by t.player") 
    org.eclipse.persistence.exceptions.QueryException.unsupportedMappingForObjectComparison(QueryException.java:1164) 

Entities

public class Player implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 



    private String name; 
    private static final long serialVersionUID = 1L; 

    public Player() { 
     super(); 
    } 

    public Long getId() { 
     return this.id; 
    } 

    /* 
    public void setId(Long id) { 
     this.id = id; 
    } 
    */ 

    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    @ManyToOne(optional = false) 
    @JoinColumn(name = "clubId", referencedColumnName = "id") 
    private Club club; 

    public Club getClub() { 
     return club; 
    } 
    public void setClub(Club club) { 
     this.club = club; 
    } 

    @Override 
    public String toString() { 
     return this.name; 
    } 
} 

public class Serie implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private Long id; 

    private int result; 
    private static final long serialVersionUID = 1L; 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date serieDate; //java.util.Date 

    /*** 
    * Convert back and forth between string and date. 
    * @return 
    */ 
    public String getSerieDate() 
    { 
     DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     String mDate = ""; 
     System.out.println(serieDate); 
     try { 
      mDate = df.format(serieDate); 
     } 
     catch (Exception ex) { 
      //ex.printStackTrace(); 
     } 

     return mDate; 
    } 

    public void setSerieDate(String aTime) { 
     DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
     try { 
      Date d = df.parse(aTime); 
      serieDate = d; 
     } 
     catch (java.text.ParseException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public Serie() { 
     super(); 
    } 

    public Long getId() { 
     return this.id; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 
    public int getResult() { 
     return this.result; 
    } 

    public void setResult(int result) { 
     this.result = result; 
    } 

    @ManyToOne(optional = false) 
    @JoinColumn(name = "clubId", referencedColumnName = "id") 
    private Club club; 

    public Club getClub() { 
     return club; 
    } 
    public void setClub(Club club) { 
     this.club = club; 
    } 

    @ManyToOne(optional = false) 
    @JoinColumn(name = "playerId", referencedColumnName = "id") 
    private Player player; 

    public Player getPlayer() { 
     return this.player; 
    } 
    public void setPlayer(Player player) { 
     this.player = player; 
    } 

    @ManyToOne(optional = false) 
    @JoinColumn(name = "serieTypeId", referencedColumnName = "id") 
    private SerieType serieType; 

    public SerieType getSerieType() { 
     return this.serieType; 
    } 
    public void setSerieType(SerieType serieType) { 
     this.serieType = serieType; 
    } 

} 




public List getSeriesForPlayer(String clubName, String playerName) 
{ 

    if (factory == null) { 
     factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME); 
    } 

    EntityManager em = factory.createEntityManager(); 

    Query q = em.createQuery("select sum(result) as total, avg(result) as snitt, s.SERIEDATE, p.NAME, c.NAME " + 
    " from jocke.serie s, jocke.player p, jocke.CLUB c" + 
    " where s.PLAYERID = p.ID" + 
    " and s.CLUBID = c.ID" + 
    " and c.NAME = '" + "BK Strået" + "'" + 
    " and p.NAME = '" + "Jocke" + "'" + 
    " group by p.name, s.SERIEDATE, c.NAME"); 

    List resultList = q.getResultList(); 
    Object obj = resultList.get(0); 

    em.close(); 

    return resultList; 
} 

xception Description: Syntax error parsing [select sum(result) as total, avg(result) as snitt, s.SERIEDATE, p.NAME, c.NAME from jocke.serie s, jocke.player p, jocke.CLUB c where s.PLAYERID = p.ID and s.CLUBID = c.ID and c.NAME = 'BK Strået' and p.NAME = 'Jocke' group by p.name, s.SERIEDATE, c.NAME]. 
[11, 17] The encapsulated expression is not a valid expression. 
+0

nicht das Problem zu sein scheint. Ich fange an zu denken, dass es etwas mit den Entitätszuordnungen zu tun hat. – user2130951

+0

Haben Sie versucht, Java-IDs (Kleinbuchstaben wie in der Klasse) für p.ID = t.PLAYERID zu verwenden? – stacker

+0

Siehe neue Ausnahme, wenn das behoben wurde. – user2130951

Antwort

3

In JPA-Abfragen müssen Sie die Eigenschaftsnamen der Entitäten verwenden. Verwenden Sie nicht ID und PLAYER, sondern id und player.

Ich denke, so etwas wie dies funktionieren soll:

Query q = em.createQuery("select t, sum(t.result) from Serie t, Player p " + 
         "  where p = t.player" + 
         "  group by t.player"); 
+0

Das ist die Schlussfolgerung, zu der ich auch gekommen bin. Aber es scheint, dass es ein zusätzliches Problem gibt. Siehe weitere Informationen zu Fehlernachrichten. Ausnahme Beschreibung: Objektvergleiche können nur mit OneToOneMappings verwendet werden. Andere Zuordnungsvergleiche müssen über Abfrageschlüssel oder direkte Vergleiche auf Attributebene durchgeführt werden. Mapping: [org.eclipse.persistence.mappings.DirectToFieldMapping [id -> PLAYER.ID]] – user2130951

+0

Ah ja, Sie vergleichen die ID des Players mit der Player-Entity selbst, denke ich. Sehen Sie meine aktualisierte Antwort. –

Verwandte Themen