JPA 2.0:为实体加载字段子集

Jus*_*ble 8 hibernate jpa

我有一个实体命名地址.地址实体有几个字段,其中一个是CITY.我通过调用entityManager.createQuery创建了一个查询,但我的查询只包含select子句中的CITY字段(因为我只想加载该字段).CITY字段的类型为String.当我得到我的resultList时,我没有得到一个Address对象列表,而是一个Object []列表.

有没有办法创建一个Address列表而不是Object []列表?我的JPA提供程序是hibernate,最新版本.我想要一个不需要使用任何Hibernate特定的解决方案.

Jör*_*ann 14

查询中的构造函数表达式可以实现这一点.通常您会将其与自定义DTO一起使用,但它也应该与实体一起使用.首先在您的实体中创建一个仅包含所需字段的附加构造函数:

public Address() {
    //default constructor
}

public Address(String city) {
    this.city = city;
}
Run Code Online (Sandbox Code Playgroud)

您的查询可能如下所示:

select new your.package.Address(a.city) from Address a where ...
Run Code Online (Sandbox Code Playgroud)

请注意,生成的对象未附加到EntityManager,因此对其的更改不会自动保留.


JB *_*zet 2

如果您请求城市,Hibernate 将如何加载 Address 实例?JPA 实体是对象,而对象应该遵守不变量。例如,一个这样的不变量可能是地址总是有 ID、街道等。如果 Hibernate 加载部分对象(仅填充城市属性),这些不变量将被破坏,并且您不能再依赖自己的代码。如果您尝试将这样的地址附加到另一个对象,或者只是尝试删除它,您也会遇到各种各样的问题,因为它甚至不再有 ID。

所以简短的回答是否定的:这是不可能的。

长的答案是,由于 Adress 是 POJO,您只需自己或使用 ResultTransformer 从加载的城市创建地址。但是您将获得暂时的 Address 实例而不是附加的 Adress 实体。恕我直言,这会导致无数错误和混乱。

  • “......这是无数错误和混乱的根源,恕我直言......”在不了解用例的情况下你怎么能这么说??? (2认同)