@SqlResultSetMapping 和 ConstructorResult 使用 BeanProperty 检查所有字段

问题描述 投票:0回答:1

我有一个旧应用程序,它使用带有本机查询的实体管理器。这些实体使用 @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方法

java spring-boot hibernate jpql entitymanager
1个回答
0
投票

我也遇到了同样的问题。我能够解决的唯一方法是确保列名称和字段名称相同。 尽管 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")
               }
       )
   }
)
© www.soinside.com 2019 - 2024. All rights reserved.