Hibernate,显示连接左边的结果是Spring

时间:2011-12-19 22:33:42

标签: java hibernate spring jsp spring-mvc

我正在学习Spring和Hibernate,而且我有一个很小但非常重要的问题。

我想从数据库中获取数据:

 Query query = session.createSQLQuery("SELECT * FROM pool a LEFT JOIN pool_question b on a.id = b.poolid");

然后将结果作为列表从我的控制器

发送到jsp文件
model.addAttribute("pools", pool);

我的数据库非常简单:

池是:

id  name    slug    date_create deactivation_date   creator_id  active

和poolquestion是

id  poolid  answer  order   question

问题是,当我试图在jsp中创建循环时:

<c:forEach items="${pools}" var="pool">
        <td><c:out value="${pool.name}" /></td>
</c:forEach>

tomcat显示错误。

当我在phpmyadmin中检查我的查询时,结果没问题。

诀窍是,当我这样查询时:

Query query = session.createQuery("FROM Pool");

jsp中的结果显示正确。

可以enyone帮助我如何在jsp中显示此查询的结果吗?

我的Pool.java是:

    package com.pool.app.domain;

// Generated 2011-12-20 12:45:22 by Hibernate Tools 3.4.0.CR1

import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * Pool generated by hbm2java
 */
@Entity
@Table(name = "pool", catalog = "pool")
public class Pool implements java.io.Serializable {

    private Integer id;
    private String name;
    private String slug;
    private Date dateCreate;
    private Date deactivationDate;
    private int creatorId;
    private int active;
    private Set<PoolQuestion> poolQuestions = new HashSet<PoolQuestion>(0);

    public Pool() {
    }

    public Pool(String name, String slug, Date dateCreate,
            Date deactivationDate, int creatorId, int active) {
        this.name = name;
        this.slug = slug;
        this.dateCreate = dateCreate;
        this.deactivationDate = deactivationDate;
        this.creatorId = creatorId;
        this.active = active;
    }

    public Pool(String name, String slug, Date dateCreate,
            Date deactivationDate, int creatorId, int active,
            Set<PoolQuestion> poolQuestions) {
        this.name = name;
        this.slug = slug;
        this.dateCreate = dateCreate;
        this.deactivationDate = deactivationDate;
        this.creatorId = creatorId;
        this.active = active;
        this.poolQuestions = poolQuestions;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

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

    @Column(name = "name", nullable = false, length = 200)
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "slug", nullable = false, length = 200)
    public String getSlug() {
        return this.slug;
    }

    public void setSlug(String slug) {
        this.slug = slug;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "date_create", nullable = false, length = 19)
    public Date getDateCreate() {
        return this.dateCreate;
    }

    public void setDateCreate(Date dateCreate) {
        this.dateCreate = dateCreate;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "deactivation_date", nullable = false, length = 19)
    public Date getDeactivationDate() {
        return this.deactivationDate;
    }

    public void setDeactivationDate(Date deactivationDate) {
        this.deactivationDate = deactivationDate;
    }

    @Column(name = "creator_id", nullable = false)
    public int getCreatorId() {
        return this.creatorId;
    }

    public void setCreatorId(int creatorId) {
        this.creatorId = creatorId;
    }

    @Column(name = "active", nullable = false)
    public int getActive() {
        return this.active;
    }

    public void setActive(int active) {
        this.active = active;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pool")
    public Set<PoolQuestion> getPoolQuestions() {
        return this.poolQuestions;
    }

    public void setPoolQuestions(Set<PoolQuestion> poolQuestions) {
        this.poolQuestions = poolQuestions;
    }

}

和PoolQuestion.java是:

    package com.pool.app.domain;

// Generated 2011-12-20 12:45:22 by Hibernate Tools 3.4.0.CR1

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * PoolQuestion generated by hbm2java
 */
@Entity
@Table(name = "pool_question", catalog = "pool")
public class PoolQuestion implements java.io.Serializable {

    private Integer id;
    private Pool pool;
    private String answer;
    private int order;
    private String question;

    public PoolQuestion() {
    }

    public PoolQuestion(Pool pool, String answer, int order) {
        this.pool = pool;
        this.answer = answer;
        this.order = order;
    }

    public PoolQuestion(Pool pool, String answer, int order, String question) {
        this.pool = pool;
        this.answer = answer;
        this.order = order;
        this.question = question;
    }

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    public Integer getId() {
        return this.id;
    }

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "poolid", nullable = false)
    public Pool getPool() {
        return this.pool;
    }

    public void setPool(Pool pool) {
        this.pool = pool;
    }

    @Column(name = "answer", nullable = false, length = 500)
    public String getAnswer() {
        return this.answer;
    }

    public void setAnswer(String answer) {
        this.answer = answer;
    }

    @Column(name = "order", nullable = false)
    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    @Column(name = "question", length = 500)
    public String getQuestion() {
        return this.question;
    }

    public void setQuestion(String question) {
        this.question = question;
    }

}

主要问题 - HQL查询应该如何看待,因为这样的查询:

Query query = session.createQuery("From Pool as p left join fetch p.id as s");

不适用于我。

4 个答案:

答案 0 :(得分:0)

没有例外,很难确切地知道出了什么问题。但是,请阅读:

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html

我认为您的问题在于您使用的是createSQLQuery而不是createQuery。即您使用的是标准SQL而不是HQL。为了帮助您入门,请尝试将查询更改为:

SELECT a.* FROM pool a LEFT JOIN ...

并拨打.addEntity(Pool.class),即session.createSQLQuery("<use above SQL>").addEntity(Pool.class);

祝你好运。

答案 1 :(得分:0)

使用Hibernate时通常不想使用本机SQL,而是使用HQL。 如果您使用的是本机查询createSQLQuery,则必须明确指定如何将值映射到POJO或指定标量 - 请参阅hibernate文档。

为什么你首先使用这个查询?你不能从Pool类的association mapping获得poolquestion值吗?这就是Hibernate的重点。

让我更清楚一点。 首先忘记查询中的连接。你不需要它。你想要POJO实例没有一些疯狂的外连接结果集。

  1. 查询所有Pool数据Query query = session.createQuery("FROM Pool");
  2. 获取包含代表您的数据List<Pool> pools = (List<Pool>) query.list();
  3. 的池实例的列表
  4. 现在你拥有它。当你要求时,所有相关数据都是由Hibernate懒散地获得的 - pool.getPoolQuestions();

答案 2 :(得分:0)

Query query = session.createQuery("from Pool");

是一个HQL查询,它会给你一个对象列表(Pool),所以没有问题可以使用:

<c:forEach items="${pools}" var="pool">
        <td><c:out value="${pool.name}" /></td>
</c:forEach>

当您使用SQL查询时,它会有所不同,您将无法获得对象列表(您必须添加一些代码和转换以获取池列表)。

这是一个例子:

@SuppressWarnings({ "unchecked", "rawtypes" })
public List<Pool> findPools()
{
    final String query = "select a.id as idAlias, a.name as nameAlias from pool a ....";
    List<Pool> list = (List<Pool>) getHibernateTemplate().execute(new HibernateCallback()
    {
        public Object doInHibernate(Session session) throws HibernateException
        {
            SQLQuery sqlQuery = session.createSQLQuery(query);
            return prepareQueryFind(sqlQuery).list();
        }
    });
    return list;
}

这里我假设你有一个像

这样的构造函数
public Pool(Integer id, String name);
/** Getters and Setters **/

如果您使用的是Hibernate版本&gt; = 3.2

@SuppressWarnings("deprecation")
private Query prepareQueryFind(SQLQuery query)
{
    return query
   .addScalar("idAlias", Hibernate.INTEGER)
   .addScalar("nameAlias", Hibernate.STRING)
   .setResultTransformer(Transformers.aliasToBean(Pool.class));
}

现在你可以这样调用fidpool:

List<Pool> poolList = poolDao.findPools();

答案 3 :(得分:0)

你可以试试这个:

Query hqlQuery = session.createQuery("from Pool as P left join P.poolQuestion");

您可以查找更多here

一些建议:
   如果您正在使用Hibernate和Spring,为什么不使用getHibernateTemplate()从表中获取数据?在这种情况下,您可以使用:

List<Pool> result = (List<Pool>) getHibernateTemplate().find("from Pool");

并且您的所有数据都将在此结果中。  有关详细信息,请参阅此example

请检查我是否正确,因为我还没有测试/模拟它。