这两个jqpl请求有什么区别?

时间:2014-09-18 12:49:40

标签: sql hibernate persistence jpql

我正在创建JPQL数据库请求。我有一个超类和两个子类;

@javax.persistence.Entity
@Inheritance( strategy = InheritanceType.JOINED )
public class SuperClass(){

@Column(columnDefinition = "INTEGER")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

// others attributes/getters and setters

}

子类:

@Entity
public class First extends SuperClass{
// attributes, getters and setters
}

@Entity
public class Second extends SuperClass{
// attributes, getters and setters
}

我正在构建一个JPQL查询来获取数据库中的First类结果。我发现一些奇怪的事。我可能会错过一些关于JPQL的东西。

String finalQuery = "SELECT distinct sup from SuperClass sup where sup.class =:myType";
Query query = em.createQuery(finalQuery);
query.setParameter("myType",First);

我在这里得到一个例外:

Caused by: java.lang.IllegalArgumentException: Parameter value [First] was not matching type [java.lang.Integer]
    at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:360) ~[hibernate-entitymanager-3.6.8.Final.jar:3.6.8.Final]
    at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:364) ~[hibernate-entitymanager-3.6.8.Final.jar:3.6.8.Final]
    at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) ~[hibernate-entitymanager-3.6.8.Final.jar:3.6.8.Final]

但如果我写

String finalQuery = "SELECT distinct sup from SuperClass sup where sup.class =First";
    Query query = em.createQuery(finalQuery);
    List<PublishableElement> resultList = query .getResultList();

没有错误。为什么?是不是可以动态传递类类型? 我真的不知道发生了什么。我认为这是其中一条:

Query query = em.createQuery(finalQuery);
    query.setParameter("myType",First);

由于

1 个答案:

答案 0 :(得分:1)

您已创建了3个类 - SuperClassFirstSecond,这些类具有类型InheritanceType.JOINED的继承策略,因此它们没有任何鉴别器列及其相应的鉴别器值。以下解释仅适用于继承类没有任何鉴别器值来区分类的情况。

现在,当你对这些类执行任何选择查询时,hibernate会做的是检查hibernate配置文件(hibernate.cfg.xml)并根据实体的顺序为每个类分配一个整数。在配置文件中声明。

例如:

如果hibernate.cfg.xml文件具有按此顺序声明的实体:

<mapping class="package.SuperClass"/>
<mapping class="package.Second"/>
<mapping class="package.First"/>

然后hibernate将这些数字分配给实体:

SuperClass - 0
Second - 1
First - 2

同样,如果实体声明如下:

<mapping class="package.SuperClass"/>
<mapping class="package.Second"/>
<mapping class="package.First"/>

然后编号

SuperClass - 0
First - 1
Second - 2

第一次查询:

String finalQuery = "SELECT distinct sup from SuperClass sup 
                     where sup.class =:myType";

Query query = em.createQuery(finalQuery);
query.setParameter("myType",First);

在此HQL中,您希望根据类类型过滤结果。根据我的上述说明,每个类都分配了一个整数,所以如果你想将它作为参数发送,那么你在query.setParameter()中传递的参数应该是一个整数。如果你想要然后你需要将整数值传递给0(假设在hibernate.cfg.xml文件的继承类中首先声明了SuperClass)。

因此,您传递的变量First必须是整数。

注意:传递一个字符串,例如:“First”到setParameter将不起作用,因为Hibernate在这种情况下需要一个整数。

第二次查询:

String finalQuery = "SELECT distinct sup from SuperClass sup 
                      where sup.class =First";

Query query = em.createQuery(finalQuery);
List<PublishableElement> resultList = query .getResultList();

在这个查询中,你直接告诉你需要类型为First的类作为String,这个查询是由Hibernate解析的,现在hibernate知道如何将这个字符串First映射到它对应的整数并准备{{ 1}}来自给定SQL select的查询。

这就是你在第一次HQL查询时获得异常而不是第二次HQL查询的原因。