在使用JPA 2.1和Hibernate 4.3.11实现的Java应用程序中,我尝试使用SqlResultSetMapping
将本地查询结果Map到实体。查询包括具有相同列名的联接的两个表,因此我需要使用别名并Map它们(此处描述了问题:(第10页)
为了简化问题,我将查询和实体压缩到最小,但这仍然会导致问题。真实的代码使用两个实体和DB函数,这就是使用原生查询而不是JPQL的原因。
网关实体:
@Entity
public class Gateway implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Integer active;
...
@Column(name = "activation_code")
private String activationCode;
...
}
SqlResultSetMapping(Sql结果集Map):
@SqlResultSetMapping(
name = "GatewayWithLoc",
entities = {
@EntityResult( entityClass = Gateway.class , fields = @FieldResult(name = "id", column = "gw_id"))
}
)
查询:
Query query = em.createNativeQuery("SELECT gw.id AS gw_id, ..., active, activation_code, ... FROM gateway gw", "GatewayWithLoc");
List<Object[]> rows = query.getResultList();
例外情况:
Caused by: org.postgresql.util.PSQLException: The column name activati2_1_0_ was not found in this ResultSet.
at org.postgresql.jdbc2.AbstractJdbc2ResultSet.findColumn(AbstractJdbc2ResultSet.java:2803)
...
如果我在SqlResultSetMapping
中使用SELECT *
而不使用fields = @FieldResult...
,代码可以按预期工作,但由于不同表中的列名相同,我无法这样做。
我将通过手动将结果Map到实体来解决这个问题,因为我需要快速的解决方案,但如果知道我做错了什么或者Hibernate不支持我正在尝试做的事情,那就太好了。Book“Pro JPA 2”包含了非常类似的示例,应该可以工作。
更新:使用Hibernate 5.1.1(Spring 4.3.2)进行测试-结果相同
更新:看起来所有的列名都需要指定,就像在多个答案中提到的那样。对我来说,这似乎是JPA/Hibernate的一个大问题-那些列名可以从实体中派生出来,只有手动指定的例外。相反,我需要写列名3次(1.查询,2.结果集Map,3.实体),这很难看,很难维护。
3条答案
按热度按时间sy5wg1nm1#
我认为您需要显式指定所有的
@FieldResult
,特别是因为两个表之间的列名存在冲突。thtygnil2#
本机查询似乎未Map到
SqlResultSetMapping
。查询中的列数比Map中的列数多得多。查询中选定的列必须与Map匹配。093gszye3#
您可以使用
SELECT NEW
:1.创建一个类,使所有需要的列都在查询中使用。
1.使用查询