我有一个实体命名地址。地址实体有几个字段,其中一个是CITY。我通过调用entityManager.createQuery创建了一个查询,但我的查询只包含select子句中的CITY字段(因为我只想加载该字段)。 CITY字段的类型为String。当我得到我的resultList时,我没有得到一个Address对象列表,而是一个Object []列表。
有没有办法创建一个Address列表而不是Object []列表?我的JPA提供程序是hibernate,最新版本。我想要一个不需要使用任何特定的Hibernate的解决方案。
答案 0 :(得分:14)
您可以在查询中使用构造函数表达式。通常您会将其与自定义DTO一起使用,但它也应该与实体一起使用。首先在您的实体中创建一个仅包含所需字段的附加构造函数:
public Address() {
//default constructor
}
public Address(String city) {
this.city = city;
}
您的查询可能如下所示:
select new your.package.Address(a.city) from Address a where ...
请注意,生成的对象未附加到EntityManager,因此对其的更改不会自动保留。
答案 1 :(得分:2)
如果您要求城市,Hibernate如何加载地址实例? JPA实体是对象,对象应该尊重不变量。例如,一个这样的不变量可能是地址总是有ID,街道等。如果Hibernate加载了部分对象(只填充了城市属性),那些不变量将被破坏,你不能再依赖自己的代码了。如果你试图将这样的地址附加到另一个对象,或者你只是想删除它,你也会遇到各种各样的问题,因为它甚至不再有ID了。
所以简短的回答是否定的:这是不可能的。
答案很长,因为Adress是一个POJO,你只需要自己从加载的城市创建地址,或者使用ResultTransformer。但是你会获得瞬态地址实例而不是附加的地址实体。这是无数错误和混乱的秘诀,恕我直言。
答案 2 :(得分:0)
有一种方法可以执行此操作,但是它涉及一些代码重复。您必须创建一个仅包含ID和CITY属性的名为“ AddressWithCityOnly”的新实体,并将其指向db(地址表)中的同一表。
然后,您可以使用此新实体对地址实体进行部分加载(加载这些实体将仅加载CITY字段),并进行部分更新(仅更新CITY字段)至地址表。
我正面临类似的问题。我有一个具有约70列和约100,000行的PERSON表,我只想更新所有行中的一列。加载原始实体会检索所有70列,这是过多的开销。