2013-12-12 17 views
5

Sembra possibile ottenere la sintassi corretta per una query jpa verso il database. Funziona perfettamente bene usando lo scoiattolo SQL.Formato corretto della query sql in java

Il database è Derby e il codice utilizza JPA.

Aggiornato con nuova query ed errore. Questo mi porta a credere che sia qualcosa nella mappatura delle entità che non è corretta. Potrebbe essere qualcosa nella clausola joinColumn?

Risolto il problema. quello stava causando il primo problema con non usando i nomi di entità corretti.

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) 

Enti

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

non sembra essere il problema. Sto iniziando a pensare che abbia qualcosa a che fare con le mappature delle entità. – user2130951

+0

Hai provato a utilizzare gli identificatori java (lettere minuscole come nella classe) per p.ID = t.PLAYERID? – stacker

+0

Vedere la nuova eccezione quando è stato corretto. – user2130951

risposta

3

nelle query JPA si devono usare i nomi delle proprietà delle Entità. Quindi non utilizzare ID e PLAYER, ma id e player.

penso che qualcosa del genere dovrebbe funzionare:

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

Questa è la conclusione a cui sono arrivato. Ma sembra che ci sia un ulteriore problema. Vedi ulteriori informazioni in questione per quanto riguarda il messaggio di errore. Descrizione dell'eccezione: i confronti tra oggetti possono essere utilizzati solo con OneToOneMappings. Altri confronti di mappatura devono essere eseguiti tramite chiavi di query o confronti a livello di attributi diretti. Mappatura: [org.eclipse.persistence.mappings.DirectToFieldMapping [id -> PLAYER.ID]] – user2130951

+0

Ah sì, si confronta l'id del giocatore con l'entità giocatore stessa penso. Vedi la mia risposta aggiornata. –