【问题标题】:Fetch returns only one item in collectionFetch 仅返回集合中的一项
【发布时间】:2017-02-01 17:26:19
【问题描述】:

表信息:

Image 表包含其父表 Media

的外键 mediaid
----------
id  | mediaid | url
========================
104 | 103     | IMG_PATH
383 | 103     | IMG_PATH
384 | 103     | IMG_PATH
395 | 103     | img_path

Media 实体拥有一组图像:

private Set<Image> images  = new HashSet<Image>(0)`;

@OneToMany(mappedBy = "media", targetEntity = Image.class ,cascade = CascadeType.ALL)
public Set<Image> getImages() {
   return images;
}

图片实体sn-p:

private Media media;
@ManyToOne
@JoinColumn(name = "mediaId")
public Media getMedia() {
    return media;
}

我实现了以下查询,它应该返回一个 Media 对象,其中包含 fk 与其提供的 id 匹配的所有图像的集合。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Media> cqObject = cb.createQuery(Media.class);
Root<Media> rootEntry = cqObject.from(Media.class);

rootEntry.fetch(Media_.images, JoinType.LEFT);              
Predicate predicate = cb.equal(rootEntry.get(Media_.id), id);           
cqObject.select(rootEntry).where(predicate);        
Media _fetcheMedia = em.createQuery(cqObject).getSingleResult();

返回的 Media 对象的集合只包含一个图像项。我确定该数据库包含指定媒体的多个图像项。

*注意Media_只是一个代表媒体实体的元模型类

id=103 的媒体对象休眠

select media0_.mediaId as mediaId1_8_0_, 
    images1_.imageId as imageId1_6_1_, 
    media0_.active as active2_8_0_, 
    media0_.created as created3_8_0_, 
    media0_.description as descript4_8_0_,
    media0_.listType as listType5_8_0_, 
    media0_.parentId as parentId6_8_0_, 
    media0_.propertyTypeId as property7_8_0_, 
    media0_.seasonId as seasonId8_8_0_, 
    media0_.status as status9_8_0_, 
    media0_.userId as userId10_8_0_, 
    images1_.active as active2_6_1_, 
    images1_.created as created3_6_1_, 
    images1_.imageTypeId as imageTyp5_6_1_, 
    images1_.imageUrl as imageUrl4_6_1_, 
    images1_.mediaId as mediaId6_6_1_, 
    images1_.mediaId as mediaId6_6_0__, 
    images1_.imageId as imageId1_6_0__ from media media0_ 
    left outer join image images1_ on media0_.mediaId=images1_.mediaId where media0_.mediaId=103

【问题讨论】:

  • 好的,当你得到 Media 对象时,图片集是加载了实体还是你需要延迟初始化的代理?
  • 我假设默认情况下它是惰性初始化,并且 rootEntry.fetch(Media_.images, JoinType.LEFT) 强制对集合进行提取。
  • 条件似乎没问题..您可以在调试模式下运行并发布生成的查询吗?
  • @MaciejKowalski ,我添加了从上面的 JPA 代码生成的休眠查询。
  • 您是否以任何方式覆盖了MediahashCodeequals

标签: mysql hibernate jpa left-join fetch


【解决方案1】:

这是我的一个愚蠢的错误,我忘记覆盖 Image 实体的 hashcode 和 equals 方法。添加了它们,它知道它应该可以正常工作。

@Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + (int) (id ^ (id >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        Image other = (Image) obj;
        if (id != other.id)
            return false;
        return true;
    }

【讨论】:

    猜你喜欢
    • 2021-02-13
    • 2017-04-17
    • 1970-01-01
    • 2016-04-06
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2017-05-16
    相关资源
    最近更新 更多