【问题标题】:What's difference between this two jqpl requests?这两个 jqpl 请求有什么区别?
【发布时间】:2014-11-12 19:38:05
【问题描述】:

我正在创建 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 class 的结果。我注意到一些奇怪的事情。我可能会错过一些关于 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);

谢谢

【问题讨论】:

标签: sql hibernate persistence jpql


【解决方案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"/>

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

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() 中传递的参数应该是一个整数。如果你想要 SuperClass 那么您需要将整数值作为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类型的类作为一个字符串,这个查询被Hibernate解析,现在hibernate知道如何把这个字符串映射到它对应的整数并准备SQL select查询来自给定的HQL

所以这就是您在第一个 HQL 查询中出现异常但在第二个 HQL 查询中没有出现异常的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 2016-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多