Hibernate Criteria 选择元组而不是对象

发布于 2024-12-12 10:48:58 字数 8801 浏览 1 评论 0原文

我正在使用 Hibernate 3.5

实体类是

package ca.cbc.medialib.entity;


@Entity
public class Category implements Serializable {

/**
 *
 */
private static final long serialVersionUID = 7909213900961217486L;
@XmlAttribute
private long id;
@XmlElement
private String title;
@XmlElement
private String fullTitle;
@XmlElement
private String description;
@XmlElement
private String bigBoxUrl;
@XmlElement
private String bannerAdUrl;
@XmlElement
private String thumbnailUrl;
@XmlElementWrapper(name = "sponsors")
@XmlElement(name = "sponsor")
private Set<Sponsor> sponsors;
private Category parent;
@XmlElementWrapper(name = "medias")
@XmlElement(name = "media")
private List<Media> medias;
@XmlElementWrapper(name = "categories")
@XmlElement(name = "category")
private List<Category> children;

private String sortField;
private String sortOrder;

private Category() {
    children = new ArrayList<Category>();
    medias = new ArrayList<Media>();
    sponsors = new HashSet<Sponsor>();
}

public Category(long id, String title, String fullTitle, String description, String bigBoxUrl, String bannerAdUrl, String thumbnailUrl) {
    this();
    this.id = id;
    this.title = title;
    this.fullTitle = fullTitle;
    this.description = description;
    this.bigBoxUrl = bigBoxUrl;
    this.bannerAdUrl = bannerAdUrl;
    this.thumbnailUrl = thumbnailUrl;
}

public void addChild(Category child) {
    child.setParent(this);
}

public void addMedia(Media media) {
    media.addCategory(this);
}

public void addSponsor(Sponsor s) {
    this.sponsors.add(s);
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Category category = (Category) o;

    if (fullTitle != null ? !fullTitle.equals(category.fullTitle) : category.fullTitle != null) return false;
    if (id != category.getId()) return false;

    return true;
}

@Column(name = "banner_ad_url")
public String getBannerAdUrl() {
    return bannerAdUrl;
}

@Column(name = "big_box_url")
public String getBigBoxUrl() {
    return bigBoxUrl;
}

@OneToMany(mappedBy = "parent")
@AccessType("field")
public List<Category> getChildren() {
    return Collections.unmodifiableList(children);
}

public String getDescription() {
    return description;
}

@Column(name = "full_title")
public String getFullTitle() {
    return fullTitle;
}

@Id
public long getId() {
    return id;
}

@ManyToMany(mappedBy = "categories")
@AccessType("field")
public List<Media> getMedias() {
    return medias;
}

@ManyToOne
@JoinColumn(name = "parent_id")
@AccessType("field")
public Category getParent() {
    return parent;
}

@Column(name = "sort_field")
public String getSortField() {
    return sortField;
}

@Column(name = "sort_order")
public String getSortOrder() {
    return sortOrder;
}

@ElementCollection
@CollectionTable(name = "sponsor", joinColumns = @JoinColumn(name = "category_id"))
@AttributeOverrides({
        @AttributeOverride(name = "imageUrl", column = @Column(name = "image_url")),
        @AttributeOverride(name = "url", column = @Column(name = "url"))})
public Set<Sponsor> getSponsors() {
    return sponsors;
}

@Column(name = "thumbnail_url")
public String getThumbnailUrl() {
    return thumbnailUrl;
}

public String getTitle() {
    return title;
}

@Override
public int hashCode() {
    int result = fullTitle != null ? fullTitle.hashCode() : (int) (id % 1000l);
    result = 31 * result;
    return result;
}

protected void internallAddMedia(Media media) {
    this.medias.add(media);
}

protected void internallRemoveMedia(Media media) {
    this.medias.remove(media);
}

public void removeChild(Category child) {
    if (children.contains(child)) {
        child.setParent(null);
    }
}

public void removeMedia(Media media) {
    media.removeCategory(this);
}


public void setBannerAdUrl(String bannerAdUrl) {
    this.bannerAdUrl = bannerAdUrl;
}

public void setBigBoxUrl(String bigBoxUrl) {
    this.bigBoxUrl = bigBoxUrl;
}

public void setDescription(String description) {
    this.description = description;
}

public void setFullTitle(String fullTitle) {
    this.fullTitle = fullTitle;
}

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

public void setParent(Category parent) {
    if (this.parent != null) {
        this.parent.children.remove(this);
    }
    this.parent = parent;
    if (parent != null) {
        parent.children.add(this);
    }
}

public void setSortField(String sortField) {
    this.sortField = sortField;
}

public void setSortOrder(String sortOrder) {
    this.sortOrder = sortOrder;
}

public void setSponsors(Set<Sponsor> l) {
    sponsors = l;
}

public void setThumbnailUrl(String thumbnailUrl) {
    this.thumbnailUrl = thumbnailUrl;
}

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

该实体与其自身具有多对一关系。

我的查询方法如下所示:

public List<T> load(int first, int ps, String sortField, SortOrder sortOrder, Map<String, String> filters) {
    logger.debug("loading lazily with page size {} and first {}", ps, first);
    logger.debug("Page size is {}", getPageSize());
    Criteria criteria = HibernateUtil.getSession().createCriteria(clazz);

    if(filters != null && filters.size()!=0){

        for (Map.Entry<String, String> e : filters.entrySet()) {
            criteria.add(Restrictions.like(e.getKey(), e.getValue()+'%'));
        }
    }
    int pn = ((Long)criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
    logger.debug("number of pages is {}", pn);
    setRowCount(pn);
    criteria.setProjection(null);

    if (sortField != null && !sortField.trim().equals("")) {
        if (sortOrder == SortOrder.DESCENDING) {
            criteria.addOrder(org.hibernate.criterion.Order.desc(sortField));
        } else {
            criteria.addOrder(Order.asc(sortField));
        }
    }


    criteria.setFirstResult(first);
    criteria.setMaxResults(first+ps);
    List<T> cats= (List<T>) criteria.list();
    logger.debug("cats found " + cats.size());
    logger.debug("first element {}", cats.get(0));
    return cats;

}

这个类的实例是用 Category 的 clazz 构造的。 问题是该方法的返回值不是列表而是元组列表。

hibernate 执行的查询和日志跟踪是

2011-10-27 14:14:01,571 DEBUG [605506535@qtp-1804533116-4] [AbstractBatcher.java:410] :即将打开PreparedStatement(打开PreparedStatements:0,全局:0) 2011-10-27 14:14:01,571 调试 [605506535@qtp-1804533116-4] [SQLStatementLogger.java:111] : 选择 this_.id 为 id0_1_, this_.banner_ad_url 作为banner2_0_1_, this_.big_box_url 为 big3_0_1_, this_.description 为 descript4_0_1_, this_.full_title 为 full5_0_1_, this_.parent_id 为parent10_0_1_, this_.sort_field 为 sort6_0_1_, this_.sort_order 为 sort7_0_1_, this_.thumbnail_url 为thumbnail8_0_1_, this_.title 为 title0_1_, 类别2_.id为id0_0_, Category2_.banner_ad_url 作为banner2_0_0_, Category2_.big_box_url 为 big3_0_0_, Category2_.description为descript4_0_0_, Category2_.full_title 为 full5_0_0_, Category2_.parent_id为parent10_0_0_, Category2_.sort_field为sort6_0_0_, Category2_.sort_order为sort7_0_0_, Category2_.thumbnail_url为thumbnail8_0_0_, 类别2_.标题为标题0_0_ 从 分类这个_ 左外连接 类别类别2_ 关于 this_.parent_id=category2_.id 限制? 2011-10-27 14:14:01,575 DEBUG [605506535@qtp-1804533116-4] [AbstractBatcher.java:426]:即将打开ResultSet(打开ResultSets:0,全局:0) 2011-10-27 14:14:01,577 调试 [605506535@qtp-1804533116-4] [Loader.java:1322] :结果行:null,EntityKey[ca.cbc.medialib.entity.Category#1] 2011-10-27 14:14:01,581 调试 [605506535@qtp-1804533116-4] [Loader.java:1322] :结果行:EntityKey[ca.cbc.medialib.entity.Category#1],EntityKey[ca。 cbc.medialib.entity.Category#11] 2011-10-27 14:14:01,582 调试 [605506535@qtp-1804533116-4] [Loader.java:1322] :结果行:EntityKey[ca.cbc.medialib.entity.Category#11],实体密钥[ca.cbc.medialib.entity.Category#111] 2011-10-27 14:14:01,582 调试 [605506535@qtp-1804533116-4] [Loader.java:1322] :结果行:EntityKey[ca.cbc.medialib.entity.Category#11],实体密钥[ca.cbc.medialib.entity.Category#112] 2011-10-27 14:14:01,595 调试 [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:69] :发现猫 4 2011-10-27 14:14:01,595 调试 [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:69] :发现猫 4 2011-10-27 14:14:01,595调试[605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:70]:第一个元素[null,ca.cbc.medialib.entity.Category@56b949d4] 2011-10-27 14:14:01,595 调试 [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:70] :第一个元素 [null, ca.cbc.medialib.entity.Category@56b949d4]

I am using Hibernate 3.5

The entity class is

package ca.cbc.medialib.entity;


@Entity
public class Category implements Serializable {

/**
 *
 */
private static final long serialVersionUID = 7909213900961217486L;
@XmlAttribute
private long id;
@XmlElement
private String title;
@XmlElement
private String fullTitle;
@XmlElement
private String description;
@XmlElement
private String bigBoxUrl;
@XmlElement
private String bannerAdUrl;
@XmlElement
private String thumbnailUrl;
@XmlElementWrapper(name = "sponsors")
@XmlElement(name = "sponsor")
private Set<Sponsor> sponsors;
private Category parent;
@XmlElementWrapper(name = "medias")
@XmlElement(name = "media")
private List<Media> medias;
@XmlElementWrapper(name = "categories")
@XmlElement(name = "category")
private List<Category> children;

private String sortField;
private String sortOrder;

private Category() {
    children = new ArrayList<Category>();
    medias = new ArrayList<Media>();
    sponsors = new HashSet<Sponsor>();
}

public Category(long id, String title, String fullTitle, String description, String bigBoxUrl, String bannerAdUrl, String thumbnailUrl) {
    this();
    this.id = id;
    this.title = title;
    this.fullTitle = fullTitle;
    this.description = description;
    this.bigBoxUrl = bigBoxUrl;
    this.bannerAdUrl = bannerAdUrl;
    this.thumbnailUrl = thumbnailUrl;
}

public void addChild(Category child) {
    child.setParent(this);
}

public void addMedia(Media media) {
    media.addCategory(this);
}

public void addSponsor(Sponsor s) {
    this.sponsors.add(s);
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    Category category = (Category) o;

    if (fullTitle != null ? !fullTitle.equals(category.fullTitle) : category.fullTitle != null) return false;
    if (id != category.getId()) return false;

    return true;
}

@Column(name = "banner_ad_url")
public String getBannerAdUrl() {
    return bannerAdUrl;
}

@Column(name = "big_box_url")
public String getBigBoxUrl() {
    return bigBoxUrl;
}

@OneToMany(mappedBy = "parent")
@AccessType("field")
public List<Category> getChildren() {
    return Collections.unmodifiableList(children);
}

public String getDescription() {
    return description;
}

@Column(name = "full_title")
public String getFullTitle() {
    return fullTitle;
}

@Id
public long getId() {
    return id;
}

@ManyToMany(mappedBy = "categories")
@AccessType("field")
public List<Media> getMedias() {
    return medias;
}

@ManyToOne
@JoinColumn(name = "parent_id")
@AccessType("field")
public Category getParent() {
    return parent;
}

@Column(name = "sort_field")
public String getSortField() {
    return sortField;
}

@Column(name = "sort_order")
public String getSortOrder() {
    return sortOrder;
}

@ElementCollection
@CollectionTable(name = "sponsor", joinColumns = @JoinColumn(name = "category_id"))
@AttributeOverrides({
        @AttributeOverride(name = "imageUrl", column = @Column(name = "image_url")),
        @AttributeOverride(name = "url", column = @Column(name = "url"))})
public Set<Sponsor> getSponsors() {
    return sponsors;
}

@Column(name = "thumbnail_url")
public String getThumbnailUrl() {
    return thumbnailUrl;
}

public String getTitle() {
    return title;
}

@Override
public int hashCode() {
    int result = fullTitle != null ? fullTitle.hashCode() : (int) (id % 1000l);
    result = 31 * result;
    return result;
}

protected void internallAddMedia(Media media) {
    this.medias.add(media);
}

protected void internallRemoveMedia(Media media) {
    this.medias.remove(media);
}

public void removeChild(Category child) {
    if (children.contains(child)) {
        child.setParent(null);
    }
}

public void removeMedia(Media media) {
    media.removeCategory(this);
}


public void setBannerAdUrl(String bannerAdUrl) {
    this.bannerAdUrl = bannerAdUrl;
}

public void setBigBoxUrl(String bigBoxUrl) {
    this.bigBoxUrl = bigBoxUrl;
}

public void setDescription(String description) {
    this.description = description;
}

public void setFullTitle(String fullTitle) {
    this.fullTitle = fullTitle;
}

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

public void setParent(Category parent) {
    if (this.parent != null) {
        this.parent.children.remove(this);
    }
    this.parent = parent;
    if (parent != null) {
        parent.children.add(this);
    }
}

public void setSortField(String sortField) {
    this.sortField = sortField;
}

public void setSortOrder(String sortOrder) {
    this.sortOrder = sortOrder;
}

public void setSponsors(Set<Sponsor> l) {
    sponsors = l;
}

public void setThumbnailUrl(String thumbnailUrl) {
    this.thumbnailUrl = thumbnailUrl;
}

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

This entity has a manyToOne relationship with itself.

My query method looks like this:

public List<T> load(int first, int ps, String sortField, SortOrder sortOrder, Map<String, String> filters) {
    logger.debug("loading lazily with page size {} and first {}", ps, first);
    logger.debug("Page size is {}", getPageSize());
    Criteria criteria = HibernateUtil.getSession().createCriteria(clazz);

    if(filters != null && filters.size()!=0){

        for (Map.Entry<String, String> e : filters.entrySet()) {
            criteria.add(Restrictions.like(e.getKey(), e.getValue()+'%'));
        }
    }
    int pn = ((Long)criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
    logger.debug("number of pages is {}", pn);
    setRowCount(pn);
    criteria.setProjection(null);

    if (sortField != null && !sortField.trim().equals("")) {
        if (sortOrder == SortOrder.DESCENDING) {
            criteria.addOrder(org.hibernate.criterion.Order.desc(sortField));
        } else {
            criteria.addOrder(Order.asc(sortField));
        }
    }


    criteria.setFirstResult(first);
    criteria.setMaxResults(first+ps);
    List<T> cats= (List<T>) criteria.list();
    logger.debug("cats found " + cats.size());
    logger.debug("first element {}", cats.get(0));
    return cats;

}

The instace of this class is constructed with and clazz of Category.
The problem is that the return value from this method is not a List but a list of tuples.

Executed query by hibernate and log trace is

2011-10-27 14:14:01,571 DEBUG [605506535@qtp-1804533116-4] [AbstractBatcher.java:410] : about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
2011-10-27 14:14:01,571 DEBUG [605506535@qtp-1804533116-4] [SQLStatementLogger.java:111] :
select
this_.id as id0_1_,
this_.banner_ad_url as banner2_0_1_,
this_.big_box_url as big3_0_1_,
this_.description as descript4_0_1_,
this_.full_title as full5_0_1_,
this_.parent_id as parent10_0_1_,
this_.sort_field as sort6_0_1_,
this_.sort_order as sort7_0_1_,
this_.thumbnail_url as thumbnail8_0_1_,
this_.title as title0_1_,
category2_.id as id0_0_,
category2_.banner_ad_url as banner2_0_0_,
category2_.big_box_url as big3_0_0_,
category2_.description as descript4_0_0_,
category2_.full_title as full5_0_0_,
category2_.parent_id as parent10_0_0_,
category2_.sort_field as sort6_0_0_,
category2_.sort_order as sort7_0_0_,
category2_.thumbnail_url as thumbnail8_0_0_,
category2_.title as title0_0_
from
Category this_
left outer join
Category category2_
on this_.parent_id=category2_.id limit ?
2011-10-27 14:14:01,575 DEBUG [605506535@qtp-1804533116-4] [AbstractBatcher.java:426] : about to open ResultSet (open ResultSets: 0, globally: 0)
2011-10-27 14:14:01,577 DEBUG [605506535@qtp-1804533116-4] [Loader.java:1322] : result row: null, EntityKey[ca.cbc.medialib.entity.Category#1]
2011-10-27 14:14:01,581 DEBUG [605506535@qtp-1804533116-4] [Loader.java:1322] : result row: EntityKey[ca.cbc.medialib.entity.Category#1], EntityKey[ca.cbc.medialib.entity.Category#11]
2011-10-27 14:14:01,582 DEBUG [605506535@qtp-1804533116-4] [Loader.java:1322] : result row: EntityKey[ca.cbc.medialib.entity.Category#11], EntityKey[ca.cbc.medialib.entity.Category#111]
2011-10-27 14:14:01,582 DEBUG [605506535@qtp-1804533116-4] [Loader.java:1322] : result row: EntityKey[ca.cbc.medialib.entity.Category#11], EntityKey[ca.cbc.medialib.entity.Category#112]
2011-10-27 14:14:01,595 DEBUG [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:69] : cats found 4
2011-10-27 14:14:01,595 DEBUG [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:69] : cats found 4
2011-10-27 14:14:01,595 DEBUG [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:70] : first element [null, ca.cbc.medialib.entity.Category@56b949d4]
2011-10-27 14:14:01,595 DEBUG [605506535@qtp-1804533116-4] [AbstractJPALazyModel.java:70] : first element [null, ca.cbc.medialib.entity.Category@56b949d4]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文