Spring / Hibernate获取包含列表

时间:2015-11-19 16:36:52

标签: java spring hibernate jpa

我正在尝试使用Hibernate从数据库中获取对象列表,但对我来说似乎很奇怪。

在DB中我有5次运行,每次3个位置。

当我从RunDao获取运行列表时,我获得了15个Run对象的列表!三个第一次运行具有相同的ID。

在我的情况下,我只想获得5次运行。我做错了吗?

如何只获得5次运行?

非常感谢

以下是我的课程Run / Position / RunDao:

Run.java

@Entity
@Table(name="kr_runs")
public class Run {

    private long id;
    private Date date;
    private int indexedPages;
    private int pr;
    @JsonIgnore
    private Site site;
    private Set<Position> positions = new HashSet<Position>(0);

    public Run() {

    }

    @Id
    @GeneratedValue
    @Column(name="id")
    public long getId() {
        return id;
    }

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

    @Temporal(value=TemporalType.TIMESTAMP)
    public Date getDate() {
        return date;
    }

    public void setDate( Date date ) {
        this.date = date;
    }

    @Column(name="indexed_pages")
    public int getIndexedPages() {
        return indexedPages;
    }

    public void setIndexedPages( int indexedPages ) {
        this.indexedPages = indexedPages;
    }

    @Column
    public int getPr() {
        return pr;
    }

    public void setPr( int pr ) {
        this.pr = pr;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "kr_site_id", nullable = false)
    public Site getSite() {
        return site;
    }

    public void setSite( Site site ) {
        this.site = site;
    }

    @Cascade({CascadeType.ALL})
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "run")
    public Set<Position> getPositions() {
        return positions;
    }

    public void setPositions( Set<Position> positions ) {
        this.positions = positions;
    }



}

Position.java

@Entity
@Table(name="kr_positions")
public class Position {

    private long id;
    private int pos;
    private String url;
    @JsonIgnore
    private Run run;
    private Keyword keyword;

    public Position() {

    }

    @Id
    @GeneratedValue
    @Column(name="id")
    public long getId() {
        return id;
    }

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

    @Column
    public int getPos() {
        return pos;
    }

    public void setPos( int pos ) {
        this.pos = pos;
    }

    @Column
    public String getUrl() {
        return url;
    }

    public void setUrl( String url ) {
        this.url = url;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "kr_run_id", nullable = false)
    public Run getRun() {
        return run;
    }

    public void setRun( Run run ) {
        this.run = run;
    }

    //@Cascade({CascadeType.SAVE_UPDATE})
    //@OneToOne(mappedBy="position")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "kr_keyword_id", nullable = false)
    public Keyword getKeyword() {
        return keyword;
    }

    public void setKeyword( Keyword keyword ) {
        this.keyword = keyword;
    }



}

RunDao.java

@Transactional
public class RunDao extends HibernateDao<Run, Long> implements IRunDao {

    public List<Run> find( long siteID, Date date_start, Date date_end ) {

        Criteria cr = currentSession().createCriteria(Run.class);
        cr.add(Restrictions.eq("site.id", siteID));
        cr.add(Restrictions.ge("date",date_start));
        cr.add(Restrictions.lt("date",date_end));

        List<Run> list = (List<Run>) cr.list();

        if (list.isEmpty()) return null;
        else return list;
    }
}

解决

感谢Guillaume的帮助,我找到了解决方案。

  • 我在Run类中替换了:

@OneToMany(fetch = FetchType.EAGER,mappedBy =“run”)

通过

@OneToMany(fetch = FetchType.LAZY,mappedBy =“run”)

  • 在我的RunsService类中,当我从DAO获得运行时,我拉出了懒惰的集合:
// Get data from DAO
List<Run> list = runDao.find(siteID, cal.getTime(), date_today);
for(Run run : list)
{
    Hibernate.initialize(run.getPositions());  // run.getPositions().size(); if you are note in @Transactional
}

1 个答案:

答案 0 :(得分:2)

代码中的所有内容都是正确的。关于@OneToMany(fetch = FetchType.EAGER ...我唯一不太确定的事情,因为过去我使用EAGER抓取类型时遇到了错误。

尝试将其保留为LAZY,然后在条件查询中添加fetch join