避免在多对多关系中不必要的加入

时间:2013-12-17 19:47:43

标签: hibernate jpa many-to-many

我的数据库中有两个表,名为media_blogmedia_category。还有一个名为media_blog_category的第三个表,它将博客与其所属的类别相关联(博客可以属于多个类别,一个类别可能包含许多博客)。这种关系在Hibernate / JPA中映射如下:

@Entity
@Table(name="media_blog")
public class Blog {
    @Column(name="name")
    private String name;

    @ManyToMany(fetch = FetchType.LAZY, targetEntity=MediaCategory.class)
    @JoinTable(name = "media_blog_category", 
        joinColumns = {@JoinColumn(name = "blog_id")}, 
        inverseJoinColumns = {@JoinColumn(name = "media_category_id")}
    )
    private Set<MediaCategory> categories;

    // Here goes the setters and getters for fields name and categories
}

@Entity
@Table(name="media_category")
public class MediaCategory {
    @Column(name="name")
    private String name;

    @ManyToMany(fetch = FetchType.LAZY, mappedBy="categories")
    private List<Blog> blogs;

    // Here goes the setters and getters for fields name and blogs
}

当我从数据库中检索博客时,使用Blog b = Blog.find(id)将以下单个查询记录到调试控制台中:

select blog0_.id as id11_0_, blog0_.name as name11_0_ 
from media_blog blog0_ where blog0_.id=?

字段categories上设置的延迟提取类型按预期工作,因为未查询类别信息。

但是在执行Set<MediaCategory> blogCategories = b.getCategories()时会执行以下查询:

select categories0_.blog_id as blog1_11_1_, 
    categories0_.media_category_id as media2_1_, 
    mediacateg1_.id as id2_0_,
    mediacateg1_.name as name2_0_ 
from media_blog_category categories0_ 
inner join media_category mediacateg1_ 
   on categories0_.media_category_id=mediacateg1_.id 
where categories0_.blog_id=?

问题是我只对类别ID感兴趣(表media_category_id中的字段media_blog_category),但我注意到查询与media_category表进行连接并检索每个类别的所有字段(在本例中为字段name,但将来会有更多字段)以填充MediaCategory对象。存在性能损失,因为它正在进行连接以获取我将不会使用的信息。

有没有办法避免Hibernate执行此连接,因此它使用MediaCategory代理填充上面的变量blogCategories(其中只有id字段可用 - 这就是我所需要的)和延迟检索其余类别字段到我调用MediaCategory代理对象的“getName()”(或另一列getter)时?

我正在尝试做的与本文中的内容类似: http://256stuff.com/gray/docs/misc/hibernate_lazy_field_access_annotations.shtml

但是对于多对多的关系。 我已经尝试过该帖子中显示的方法,因此使用idMediaCategory课程中注释了@AccessType("property")字段,但它不起作用。它似乎不适合多对多关系,但仅适用于一对一的关系。

谢谢!

0 个答案:

没有答案