我有一个旧应用程序,它使用带有本机查询的实体管理器。这些实体使用 @SqlResultSetMapping 进行注释,并使用 @ConstructorResult。该应用程序在旧版本的 Hibernate 上运行良好。然而,更新到hibernate 6.2之后。该应用程序不再能够映射字段。
例如,假设我有一个本机查询“
SELECT FIRST_NAME from PERSON
”
假设我有一个实体
@SqlResultSetMapping(
name = "MAPPING_PERSON",
classes = {
@ConstructorResult(
targetClass = PersonPOJO.class,
columns = {
@ColumnResult(name = "FIRST_NAME")
}
)
}
)
@Entity
@Getter
@Setter
public class Person {
private Long id;
private String firstname;
}
假设我有一个名为 PersonPOJO 的类
public class PersonPOJO {
private String firstname;
public Person(String firstname) {
this.firstname = firstname;
}
public String getFirstname() {
return this.firstname;
}
public String setFirstname(String firstname) {
this.firstname = firstname;
}
}
当我使用
entityManager.createNativeQuery(sqlQuery, "MAPPING_PERSON")
时,出现休眠实例化异常,无法设置字段“FIRST_NAME”来实例化。
我尝试调试,发现hibernate在内部使用DynamicInstantiationAssemblerInjectionImpl,并且该类使用Class.java的findField方法
我也遇到了同样的问题。我能够解决的唯一方法是确保列名称和字段名称相同。 尽管 ConstructorResult 的 Hibernate 6 JavaDoc 声明顺序很重要,但给出的示例也显示名称匹配。
在你的情况下这应该有效:
entityManager.createNativeQuery("select FIRST_NAME as firstname from person", "MAPPING_PERSON")
和
@SqlResultSetMapping(
name = "MAPPING_PERSON",
classes = {
@ConstructorResult(
targetClass = PersonPOJO.class,
columns = {
@ColumnResult(name = "firstname")
}
)
}
)