在查询中使用子计数时,Hibernate生成的MySQLSyntaxErrorException

时间:2013-07-31 07:37:16

标签: mysql hibernate jpa-2.0 jpql

我有一个查询,其中我只想检索具有一个或多个Link子项的Message对象。

我的留言课是:

package zzz.community.domain;

/**
* Entity implementation class for Entity: Message.
*/
@Entity
@Table(name = "MESSAGE")
public class Message implements Serializable {

private static final long serialVersionUID = 2252587276028343749L;

public static final int MAX_LENGTH_TITLE = 255;

public static final int MAX_LENGTH_TEXT = 200000;

@Id @GeneratedValue
private Long id;

private String title;

@Column(columnDefinition = "TEXT")
private String text;

/**
 * The date at which the message was posted.
 */
private Date creationDate;

/**
 * The profile id of the user that posted this message.
 */
@OneToOne
private Profile creator;

/**
 * The id of the circle the message was posted to.
 */
@OneToOne
private Circle circle;

/**
 * When true, only members of the circle may see this message.
 */
private Boolean membersOnly;

@OneToMany(mappedBy="message")
@OrderBy("id DESC")
private Set<Link> links;

public Long getId() {
    return id;
}

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

public String getText() {
    return text;
}

public void setText(final String text) {
    this.text = text;
}

public String getTitle() {
    return title;
}

public void setTitle(final String title) {
    this.title = title;
}

public Date getCreationDate() {
    return creationDate;
}

public void setCreationDate(final Date creationDate) {
    this.creationDate = creationDate;
}

public Profile getCreator() {
    return creator;
}

public void setCreator(final Profile creator) {
    this.creator = creator;
}

public Circle getCircle() {
    return circle;
}

public void setCircle(final Circle circle) {
    this.circle = circle;
}

public Boolean getMembersOnly() {
    return membersOnly;
}

public void setMembersOnly(final Boolean membersOnly) {
    this.membersOnly = membersOnly;
}

public Set<Link> getLinks() {
    return this.links;
}

public void setLinks(final Set<Link> links) {
    this.links = links;
}

public void addLink(final Link link) {
    this.links.add(link);
}

}

我写的JPA查询是:

 select m from Message m 
 where m.circle = :circle 
 and count(m.links) > 0
 order by m.creationDate DESC

Hibernate正确解析此代码(无AST异常),但生成的mysql语句不正确并抛出MySQLSyntaxErrorException

09:01:22.153 [http-apr-8080-exec-3] DEBUG org.hibernate.hql.ast.ErrorCounter - throwQueryException() : no errors
09:01:22.154 [http-apr-8080-exec-3] DEBUG o.h.hql.ast.QueryTranslatorImpl - HQL: select m from zzz.domain.Message m where m.circle = :circle and count(m.links) > 0 order by m.creationDate DESC
09:01:22.154 [http-apr-8080-exec-3] DEBUG o.h.hql.ast.QueryTranslatorImpl - SQL: select message0_.id as id3_, message0_.circle_id as circle6_3_, message0_.creationDate as creation2_3_, message0_.creator_id as creator7_3_, message0_.membersOnly as membersO3_3_, message0_.text as text3_, message0_.title as title3_ from MESSAGE message0_ cross join LINK links1_ where message0_.id=links1_.message_id and message0_.circle_id=? and count(.)>0 order by message0_.creationDate DESC

再次,得到的MySQL查询:

select 
  message0_.id as id3_
, message0_.circle_id as circle6_3_
, message0_.creationDate as creation2_3_
, message0_.creator_id as creator7_3_
, message0_.membersOnly as membersO3_3_
, message0_.text as text3_
, message0_.title as title3_ 
from MESSAGE message0_ 
cross join LINK links1_ 
where message0_.id=links1_.message_id 
and   message0_.circle_id=? 
and   count(.)>0 
order by message0_.creationDate DESC

当然,解决方法是删除选择标准

count(m.links) > 0

并将其替换为java中的一些代码。但我希望能得到更好的建议。
先谢谢,

亨克

1 个答案:

答案 0 :(得分:1)

在JPQL中,这可以通过以下结构之一来完成:

  • 空集合比较表达式IS [NOT] EMPTY
  • SIZE功能

第一个跟随:

count(m.links) > 0

替换为:

m.links IS NOT EMPTY

第二种方法是:

SIZE(m.links) > 0