Hibernate 4、JPA 2 和 HSQL,无法通过 ID 查询

Posted

技术标签:

【中文标题】Hibernate 4、JPA 2 和 HSQL,无法通过 ID 查询【英文标题】:Hibernate 4, JPA 2 and HSQL, not able to query by ID 【发布时间】:2012-10-26 20:32:02 【问题描述】:

我有一个名为 Service 的域对象,其中包含一个 id 字段:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id", nullable = false)
private Integer id;

@Column(name = "type")
private Service.ServiceTypes serviceType;

在我的 DAO 实现中,我可以通过 serviceType 轻松查询:

@Override
    public Set<Service> queryDatabaseByServiceType(ServiceTypes serviceType) 
        logger.debug("Querying the database by service type " + serviceType.toString());
        return new HashSet<Service>(super.entityManager.createQuery("from Service s where s.type = :serviceType").setParameter("serviceType", serviceType).getResultList());
    

当我复制并通过该方法并尝试针对“id”运行查询时,我得到零结果。

@Override
    public Service queryDatabaseByServiceId(int id) 
List<Service> results = super.entityManager.createQuery("from Service s where s.id = :id").setParameter("id", id).getResultList();
return results.get(0);

总是什么都不返回...我已经尝试过一百万种不同的方法...

CriteriaBuilder builder = super.entityManager.getCriteriaBuilder();
CriteriaQuery<Service> criteria = builder.createQuery(Service.class);
Root<Service> s1 = criteria.from(Service.class);
TypedQuery<Service> query = super.entityManager.createQuery(
    criteria.select(s1).where(builder.equal(s1.get("id"), id)));
Service service = query.getSingleResult();
return service;

还是什么都没有。我不确定为什么我可以查询其他列但不能查询 ID。我已经验证了我传入的 ID 是有效的,没有任何效果。

有什么想法吗?

编辑:这是我尝试查询的其他方法:

Service ser = super.entityManager.find(Service.class, new Integer(1));

List z1 = super.entityManager.createQuery("select s.id from Service s").getResultList();

List results1 = super.entityManager.createQuery("SELECT s FROM Service s WHERE id = 1").getResultList();

List<Service> results = super.entityManager.createQuery("from Service as s where s.id = :id").setParameter("id", new Integer(1)).getResultList();

我尝试将我的域对象中的字段更改为“idx”而不是“id”,我尝试将列名更改为“service_id”,认为它用于 id 字段的内容之间可能存在一些内部冲突和我的对象,但仍然没有。如前所述和 cmets 中所述,通过任何其他字段进行查询都可以正常工作,并且我可以轻松获得显示 ID 的结果:

return new HashSet<Service>(super.entityManager.createQuery("from Service s where s.type = :serviceType").setParameter("serviceType", serviceType).getResultList());

生成一个填充列表,当转换为 json 时,我在浏览器中看到:

"services":["id":2,"serviceType":"x",.....

对于所有这些不同类型的查询,这里是日志输出:

DEBUG: service.impl.ServiceServiceImpl - Querying the database by service id 2
Hibernate: select service0_.service_id as service1_0_, service0_.description as descript2_0_, service0_.name as name0_, service0_.type as type0_, service0_.tmodel as tmodel0_, service0_.uddi_id as uddi6_0_, service0_.url as url0_, service0_.version as version0_ from services service0_ where service0_.service_id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - 1
INFO : service.impl.ServiceServiceImpl - results list from id query: 0
Hibernate: select service0_.service_id as service1_0_0_, service0_.description as descript2_0_0_, service0_.name as name0_0_, service0_.type as type0_0_, service0_.tmodel as tmodel0_0_, service0_.uddi_id as uddi6_0_0_, service0_.url as url0_0_, service0_.version as version0_0_ from services service0_ where service0_.service_id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - 1
Hibernate: select service0_.service_id as col_0_0_ from services service0_
INFO : service.impl.ServiceServiceImpl - z1 count: 0
Hibernate: select service0_.service_id as service1_0_, service0_.description as descript2_0_, service0_.name as name0_, service0_.type as type0_, service0_.tmodel as tmodel0_, service0_.uddi_id as uddi6_0_, service0_.url as url0_, service0_.version as version0_ from services service0_ where service0_.service_id=1
INFO : service.impl.ServiceServiceImpl - results1 from id query: 0
Hibernate: select service0_.service_id as service1_0_, service0_.description as descript2_0_, service0_.name as name0_, service0_.type as type0_, service0_.tmodel as tmodel0_, service0_.uddi_id as uddi6_0_, service0_.url as url0_, service0_.version as version0_ from services service0_ where service0_.service_id=2
INFO : service.impl.ServiceServiceImpl - results2 from id query: 0
Hibernate: select service0_.service_id as service1_0_0_, service0_.description as descript2_0_0_, service0_.name as name0_0_, service0_.type as type0_0_, service0_.tmodel as tmodel0_0_, service0_.uddi_id as uddi6_0_0_, service0_.url as url0_0_, service0_.version as version0_0_ from services service0_ where service0_.service_id=?
TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - 2

【问题讨论】:

不知道,但你为什么不直接使用Service s = em.find(Service.class, id); 我确实试过了——也没有结果......就像它存储 ID 的方式与预期不同 【参考方案1】:

我们项目中使用的是JPA2,但是没有这种问题,不如把“public Service queryDatabaseByServiceId(int id)”id类型改成Integer,在我看来,在hibernate Integer会是一个更好的选择。让我知道发生了什么。另一件事是更改 log4j 以打印 sql 以及检查它的参数值。

<logger name="org.hibernate.type">
    <level value="trace"></level>
</logger>
<logger name="org.hibernate.sql">
    <level value="trace"></level>
</logger>

【讨论】:

我已经尝试过使用 Integer,但仍然没有。我把id的表名改成service_id就是为了看看有没有什么奇怪的注释。这是从休眠中创建的行: Hibernate: create table services (service_id integer not null, description varchar(255), name varchar(255), type integer, tmodel varchar(255), uddi_id varchar(255), url varchar(255) ), 版本 varchar(255), 主键 (service_id)) 我可以将数据库写入文件而不是内存中,以便直接查看表/列/值吗? 没有。其实就是log4j,你把我贴的代码加进去就可以看到参数值了。 当我运行查询时,我可以在日志中看到:TRACE: org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - 2,但它仍然返回零结果。当我按服务类型查询时,它返回结果: "services":["id":2,"serviceType": "x"....... 好吧,事实证明我犯了一个大错——我将结果存储在内存和数据库中的映射中。我认为有效的查询实际上是使用地图,而不是查询数据库。结果是,所有查询都返回 0 个项目,包括“findAll()”。我在这里开了一个新问题***.com/questions/13111077/…

以上是关于Hibernate 4、JPA 2 和 HSQL,无法通过 ID 查询的主要内容,如果未能解决你的问题,请参考以下文章

在语句中找不到 Spring Hibernate JPA HSQL 表

用于 HSQL 的宠物诊所 hibernate.dialect

ORM 解决方案(JPA;Hibernate)与 JDBC

JPA/Hibernate/HSQLDB 查询但不分配子对象

为啥需要传统的 Hibernate?

在不同情况下使用不同的 Hibernate 用户类型