[英]JPA/Hibernate + HQL/JPQL: select DTO with BigDecimal parameter
[英]JPQL/HQL: select with OR fails
我的查询有一些问题,但不知道确切的位置。
该查询返回例如3个Change对象:
select c from Change c where c.entityOne.serial = 'TEST3'
该查询返回例如2个Change对象:
select c from Change c where c.entityTwo.serial = 'TEST3'
但是当我期望3到5之间的值时,此查询返回0。
select c from Change c where (c.entityOne.serial = 'TEST3' or c.entityTwo.serial = 'TEST3')
我哪里错了? 如果您需要更多代码,请询问。
进行测试:
很抱歉,有很多代码,但是重现此问题是必需的。
Change.java
@Entity
public class Change {
private long id;
private EntityOne entityOne;
private EntityTwo entityTwo;
@Id
@GeneratedValue
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@ManyToOne
public EntityOne getEntityOne() {
return entityOne;
}
public void setEntityOne(EntityOne entityOne) {
this.entityOne = entityOne;
}
@ManyToOne
public EntityTwo getEntityTwo() {
return entityTwo;
}
public void setEntityTwo(EntityTwo entityTwo) {
this.entityTwo = entityTwo;
}
}
EntityOne.java和EntityTwo.java(仅重命名该类)
@Entity
public class EntityOne {
private long id;
private String serial;
@Id
@GeneratedValue
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getSerial() {
return serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
}
Test.java-运行它。
public class Test {
private static EntityManagerFactory buildFactory() {
try {
return Persistence.createEntityManagerFactory("migration-tool");
} catch (Throwable ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
EntityManagerFactory emf = buildFactory();
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("select c from Change c where (c.entityOne.serial = 'TEST3' or c.entityTwo.serial = 'TEST3')");
List<Change> changeRecords = q.getResultList();
System.out.println(changeRecords.size());
emf.close();
}
}
persistence.xml中
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">
<persistence-unit name="migration-tool" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>test.Change</class>
<class>test.EntityOne</class>
<class>test.EntityTwo</class>
<properties>
<property name="hibernate.search.autoregister_listeners" value="false"/>
<property name="hibernate.cache.region.factory_class"
value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>
<property name="hibernate.cache.use_query_cache" value="true"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://127.0.0.1:5434/test"/>
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="123456"/>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
</properties>
</persistence-unit>
</persistence>
pom.xml中的依赖项
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901.jdbc4</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.4.2</version>
</dependency>
和SQL脚本一起填写数据。
CREATE TABLE entityone
(
id bigint NOT NULL,
serial character varying(255),
PRIMARY KEY (id)
);
CREATE TABLE entitytwo
(
id bigint NOT NULL,
serial character varying(255),
PRIMARY KEY (id)
);
CREATE TABLE change
(
id bigint NOT NULL,
entityone_id bigint,
entitytwo_id bigint,
PRIMARY KEY (id),
FOREIGN KEY (entityone_id) REFERENCES entityone(id),
FOREIGN KEY (entitytwo_id) REFERENCES entitytwo(id)
);
insert into entityone values (1, 'TEST3');
insert into entityone values (2, 'TEST1');
insert into entityone values (3, 'TEST2');
insert into entityone values (4, 'TEST3');
insert into entitytwo values (1, 'TEST3');
insert into entitytwo values (2, 'TEST3');
insert into entitytwo values (3, 'TEST4');
insert into entitytwo values (4, 'TEST3');
insert into change values (1, 1, NULL);
insert into change values (2, 2, NULL);
insert into change values (3, 3, NULL);
insert into change values (4, 4, NULL);
insert into change values (5, NULL, 1);
insert into change values (6, NULL, 2);
insert into change values (7, NULL, 3);
insert into change values (8, NULL, 4);
用评论写出答案:
问题是NULL
值。 Hibernate文档(v 4.3)的第16.4章规定:
16.4。 连接语法的形式
HQL支持两种形式的关联连接:隐式和显式。
上一节中显示的查询全部使用显式形式,即在from子句中显式使用join关键字。 这是推荐的形式。
隐式形式不使用join关键字。 而是使用点符号“取消引用”关联。 隐式联接可以出现在任何HQL子句中。 隐式联接会在结果SQL语句中进行内部联接 。
来自Cat,作为cat,其中cat.mate.name类似于'%s%'
我已经加粗了最相关的部分。 这说明您的点表示法将被展开到内部联接中,并且由于键为空-您的实体将不会出现在联接中。
Hibernate执行的SQL也显示了这一点(为了便于阅读,下面将其美化):
select change
from Change change, EntityOne entityone, EntityTwo entitytwo
where
change.entityOne_id=entityone.id and
change.entityTwo_id=entitytwo.id and
(
((change.entityOne_id is not null) and entityone.serial='TEST3') or
((change.entityTwo_id is not null) and entitytwo.serial='TEST3')
)
不幸的是,点符号不能使您获得理想的结果。 您必须自己创建联接,如上面的文档第16.3章中所述。 例:
SELECT c
FROM Change AS c
LEFT JOIN Change.entityOne as entityOne
LEFT JOIN Change.entityTwo as entityTwo
WHERE
entityOne.serial = "TEST3" OR entityTwo.serial = "TEST3"
注意:我没有Hibernate的有效安装程序,您可能必须在上面添加额外的null检查
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.