Hibernate外键关系--list()使得不必要的sql查询 - 忽略setMaxResults

时间:2010-12-21 14:17:58

标签: hibernate list

首先,这是我第一次使用Hibernate,所以我的问题可能看起来很幼稚。

我有两张桌子,DsJobs和DsEvents。事件在DsJobs表上具有外键关系(DsJobs表中的EID列对应于DsEvents表的ID列)。

我用anotations创建了映射,我关心的是单边关系,所以我在DsJobs表中有一个'dsEvents'属性,用@ManyToOne注释:

@Entity
@Table(name="DsJobs")
public class DsJobs  implements java.io.Serializable {

...

     private DsEvents dsEvents;
   ...

     @Id
    @Column(name="JID", unique=true, nullable=false)
    public long getJid() {
        return this.jid;
    }

    public void setJid(long jid) {
        this.jid = jid;
    }

@ManyToOne
    @JoinColumn(name="eid")

    public DsEvents getDsEvents() {
        return this.dsEvents;
    }

    public void setDsEvents(DsEvents dsEvents) {
        this.dsEvents = dsEvents;
    }
....
}

我想从数据库中检索Jobs记录列表,并使用setFirstResult和setMaxResults限制它们。这是我的电话:

return (ArrayList<DsJobs>) this.sessionFactory.getCurrentSession().createQuery("from DsJobs log").setFirstResult(start).setMaxResults(rows).list();

此代码返回DsJobs对象的ArrayList,并且在每个DsJobs对象中都有一个DsEvents对象,正确实例化。

我的问题是两个:

  1. 当我看到HQL被执行时,会对数据库进行不必要的SELECT调用,每个DsJobs记录一次。因此,对于每个DsJobs记录,DsEvents中有一个SELECT来按事件id获取相应的事件。这对性能来说是不可接受的,因为使用简单的JDBC我可以通过内部连接SELECT stament获得我需要的所有数据。我可能做了一些完全错误的事情,请告诉我什么,如果你知道我该怎么做。

  2. Hibernate似乎完全忽略了setFirstResult和setMaxResults,我总是从数据库中获取所有记录。我该如何解决这个问题?

  3. 我将非常感谢任何帮助。

    提前谢谢。

2 个答案:

答案 0 :(得分:1)

  

当我看到HQL被执行时,对数据库进行了不必要的SELECT调用,每个DsJobs记录都有一个。

是的,这是可怕的n + 1选择问题。只有在对关系强制执行某些RI约束时才会发生这种情况(例如,一对一或唯一约束)。您向我们展示的映射似乎没有出现这些问题,这让我觉得您没有向我们展示导致您遇到麻烦的实际映射。请发布实际代码,而不是它的一些通用缩写版本。

  

Hibernate似乎完全忽略了setFirstResult和setMaxResults,我总是从数据库中获取所有记录。我该如何解决这个问题?

此代码也没问题。这意味着你没有向我们展示导致你麻烦的实际代码。

答案 1 :(得分:0)

对于1,您可能想要了解Lazy / Eager加载。在您的情况下,您似乎希望Eager加载,即一次检索所有数据。有关详细信息,请参阅此Wiki页面:http://community.jboss.org/wiki/AShortPrimerOnFetchingStrategies

对于2,您的使用听起来是正确的。我需要更多细节才能看出它是错误的。