gpt4 book ai didi

java - 将 Hibernate 查询结果映射到自定义类?

转载 作者:IT老高 更新时间:2023-10-28 13:55:57 28 4
gpt4 key购买 nike

跟进我昨天发布的一个问题:How to populate POJO class from custom Hibernate query?

谁能告诉我如何在 Hibernate 中编写以下 SQL 并正确获得结果的示例?

SQL:

select firstName, lastName
from Employee

如果在 Hibernate 中可能的话,我想做的是将结果放在它们自己的基类中:

class Results {
private firstName;
private lastName;
// getters and setters
}

我相信在 JPA 中是可能的(使用 EntityManager),但我还没有弄清楚如何在 Hibernate 中做到这一点(使用 SessionFactorySession)。

我正在尝试更好地学习 Hibernate,即使是这个“简单”的查询也被证明令人困惑,无法知道 Hibernate 返回结果的形式,以及如何将结果映射到我自己的(基)类中。所以在 DAO 例程结束时,我会这样做:

List<Results> list = query.list();

返回 ResultsList(我的基类)。

最佳答案

select firstName, lastName from Employee

query.setResultTransformer(Transformers.aliasToBean(MyResults.class));

由于异常,您不能将上述代码用于 Hibernate 5 和 Hibernate 4(至少是 Hibernate 4.3.6.Final)

java.lang.ClassCastException: com.github.fluent.hibernate.request.persistent.UserDto cannot be cast to java.util.Map
at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102)

问题在于 Hibernate 将列名的别名转换为大写 - firstName 变为 FIRSTNAME。它会尝试在 DTO 中找到名称为 getFIRSTNAME() 的 getter,并使用此类策略在 DTO 中找到 setter setFIRSTNAME()

    PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl(
PropertyAccessStrategyBasicImpl.INSTANCE,
PropertyAccessStrategyFieldImpl.INSTANCE,
PropertyAccessStrategyMapImpl.INSTANCE
);

在 Hibernate 看来,只有 PropertyAccessStrategyMapImpl.INSTANCE 适合。因此,之后它会尝试进行转换 (Map)MyResults.

public void set(Object target, Object value, SessionFactoryImplementor factory) {
( (Map) target ).put( propertyName, value );
}

不知道,这是一个错误或功能。

如何解决

使用带引号的别名

public class Results {

private String firstName;

private String lastName;

public String getFirstName() {
return firstName;
}

public String getLastName() {
return lastName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

}

String sql = "select firstName as \"firstName\",
lastName as \"lastName\" from Employee";

List<Results> employees = session.createSQLQuery(sql).setResultTransformer(
Transformers.aliasToBean(Results.class)).list();

使用自定义结果转换器

解决问题的另一种方法 - 使用忽略方法名称大小写的结果转换器(将 getFirstName() 视为 getFIRSTNAME())。您可以自己编写或使用 FluentHibernateResultTransformer .您将不需要使用引号和别名(如果您的列名等于 DTO 名称)。

只需从项目页面下载库(不需要额外的 jar):fluent-hibernate .

String sql = "select firstName, lastName from Employee";
List<Results> employees = session.createSQLQuery(sql)
.setResultTransformer(new FluentHibernateResultTransformer(Results.class))
.list();

这个转换器也可以用于嵌套投影:How to transform a flat result set using Hibernate

关于java - 将 Hibernate 查询结果映射到自定义类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37420401/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com