1

我有一个查询,我只想检索具有一个或多个 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] 调试 org.hibernate.hql.ast.ErrorCounter - throwQueryException():没有错误
09:01:22.154 [http-apr-8080-exec-3] 调试 ohhql.ast.QueryTranslatorImpl - HQL:从 zzz.domain.Message m 中选择 m,其中 m.circle = :circle 和 count(m.links) > 0按 m.creationDate DESC 排序
09:01:22.154 [http-apr-8080-exec-3] 调试 ohhql.ast.QueryTranslatorImpl - SQL:选择 message0_.id 作为 id3_,message0_.circle_id 作为 circle6_3_,message0_.creationDate 作为 creation2_3_,message0_.creator_id 作为 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=? 并且 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中的一些代码替换它。但我希望得到你们中的一个更好的建议。
提前致谢,

亨克

4

1 回答 1

1

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

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

第一个如下:

count(m.links) > 0

替换为:

m.links IS NOT EMPTY

第二种方法是:

SIZE(m.links) > 0
于 2013-07-31T16:50:41.173 回答