我如何编写一个Hibernate Criteria查询,为一个超类,并检查某个子类? [英] How can I write a Hibernate Criteria query, for a super-class, and check for a certain sub-class?

查看:146
本文介绍了我如何编写一个Hibernate Criteria查询,为一个超类,并检查某个子类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何编写Hibernate Criteria查询,查找超级类,并检查某个子类?让我们想象一下,我们有以下类所有的Hibernate映射JPA起来:

  @Entity 
@Inheritance(策略=继承类型.JOINED)
public class Bar {
@Id
@Column(name =id)
private Long id;
}

@Entity
@PrimaryKeyJoinColumn(NAME = bar_id)
公共类Foo就继承了Bar {
}

@Entity
@PrimaryKeyJoinColumn(名称= bar_id)
公共类咕延伸酒吧{
}

在编写这样的Criteria查询时,为了提高性能,我希望对子类使用左连接:

 的getSession()
.createCriteria(Bar.class)
.createAlias( 富, 富,CriteriaSpecification.LEFT_JOIN)
。新增(Restrictions.isNotNull(foo.bar_id))
.list();

这个失败了,因为关联路径Foo显然不起作用,但它会说明什么我想要。或者有另一种做这种查询的方法吗?我需要查询在超类上执行。如果我在SQL中完成它,它将如下所示:

  select b。* 
from bar b left在f.bar_id = b.id
处加入foo f,其中f.bar_id不为null;

上面的SQL查询只是为了说明我的意思,我知道使用a 正常加入该特定情况。

解决方案

确实不清楚您想要做什么。



首先,由于Foo从Bar继承,因此搜索Bar实例将自动返回Foo实例。 Hibernate负责自己加入表。



其次:你的SQL查询真的很奇怪。你正在做一个左连接(这意味着你正在寻找可能没有关联foo的酒吧),但是你也有一个关于foo.bar_id不为空的位置。这实际上构成了一个内部连接,并且可以被重写为:

  select b。* from bar b inner join foo f on f .bar_id = b.id 

如果你想要做的只是搜索Foos和Foos,然后使用标准与富作为根实体:

 的getSession()
.createCriteria(让Foo.class)
.list();

您将获得Foo实例,但由于Foo扩展Bar,这些Foo实例也是Bar实例。这就是继承。



现在,如果您要动态构建Criteria实例,并且在某些时候意识到搜索只能返回Foo的实例,则必须使用隐式类属性:

$ p $ Criteria c = getSession()。createCriteria(Bar.class,bar)
// ...
if(limitToFoos){
c.add(Restrictions.eq(bar.class,Foo.class));
}


How can I write a Hibernate Criteria query, for a super-class, and check for a certain sub-class? Let's imagine we have the following classes all mapped up with Hibernate-JPA:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Bar {
    @Id
    @Column(name = "id")
    private Long id;
}

@Entity
@PrimaryKeyJoinColumn(name="bar_id")
public class Foo extends Bar {
}

@Entity
@PrimaryKeyJoinColumn(name="bar_id")    
public class Goo extends Bar {
}

When writing a Criteria query like this, I would like, for performance, to use a left-join with the sub-class:

getSession()
    .createCriteria(Bar.class)
    .createAlias("Foo", "foo", CriteriaSpecification.LEFT_JOIN)
    .add(Restrictions.isNotNull("foo.bar_id"))
    .list();

This fails, because the association path "Foo" doesn't work obviously, but it will illustrate what I want. Or is there another way of doing this type of query? I need the query to be performed on the superclass. If I would have done it in SQL it would look like this:

select b.*
from bar b left join foo f on f.bar_id = b.id
where f.bar_id is not null;

The SQL query above is just to illustrate what I mean, I know it would be easier to use a "normal" join in that specific case.

解决方案

It's really not clear what you want to do.

First of all, since Foo inherits from Bar, searching for Bar instances will automatically return Foo instances. Hibernate takes care of joining the tables by itself.

Second: your SQL query is really strange. You're doing a left join (which means that you're searching for bars who might not have an associated foo), but you also have a where close on foo.bar_id being not null. This in fact constitutes an inner join, and could be rewritten as

select b.* from bar b inner join foo f on f.bar_id = b.id

If what you want to do is search for Foos, and Foos only, then use a Criteria with Foo as root entity:

getSession()
    .createCriteria(Foo.class)
    .list();

You will get Foo instances, but since Foo extends Bar, these Foo instances are also Bar instances. That's what inheritance is.

Now if you're building your Criteria instance dynamically, and realize at some point that the search must only return instances of Foo, you have to use the implicit class property:

Criteria c = getSession().createCriteria(Bar.class, "bar")
// ...
if (limitToFoos) {
    c.add(Restrictions.eq("bar.class", Foo.class));
}

这篇关于我如何编写一个Hibernate Criteria查询,为一个超类,并检查某个子类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆