2013-12-12 34 views
5

我似乎可以得到正確的數據庫jpa查詢語法。它使用松鼠SQL完美無瑕。正確的格式在java中的sql查詢

數據庫是Derby,代碼使用的是JPA。

更新爲新的查詢和錯誤。這導致我相信它是在實體映射中是不正確的。這可能是在joinColumn子句中的東西?

修復了命名。這是導致第一個問題沒有使用正確的實體名稱。

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) 

實體

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

似乎並不成爲問題。我開始認爲它與實體映射有關。 – user2130951

+0

您是否嘗試過使用p.ID = t.PLAYERID的java標識符(小寫和小寫類似)? – stacker

+0

修復時請查看新的例外情況。 – user2130951

回答

3

在JPA查詢,您必須使用實體的屬性名稱。所以不要使用ID和PLAYER,但是請使用idplayer

我覺得這樣的事情應該工作:

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

這也是我也得出的結論。但似乎還有一個額外的問題。請參閱有關錯誤消息的其他信息。異常說明:對象比較只能與OneToOneMappings一起使用。其他映射比較必須通過查詢鍵或直接屬性級別比較來完成。 映射:[org.eclipse.persistence.mappings.DirectToFieldMapping [id - > PLAYER.ID]] – user2130951

+0

啊,是的,你比較玩家的身份和球員實體本身我認爲。看到我更新的回覆。 –