Hibernate Transformers.aliasToBean找不到属性方法

还原现场:在mysql环境下,以下代码,在mysql下运行正常,但是切换到oralce,报出找不到STUDENTNAME属性的错误。
 
1List resultWithAliasedBean = s.createSQLQuery(
2  "SELECT st.name as studentName, co.description as courseDescription " +
3  "FROM Enrolment e " +
4  "INNER JOIN Student st on e.studentId=st.studentId " +
5  "INNER JOIN Course co on e.courseCode=co.courseCode")
6  .setResultTransformer( Transformers.aliasToBean(StudentDTO.class))
7  .list();
 
分析:原来是oracle自动将列映射的studentName转换为大写的STUDENTNAME,所以不能映射,报类找不到STUDENTNAME的set方法。
解决办法:添加addScalar方法,代码如下:
 
01List resultWithAliasedBean = s.createSQLQuery(
02  "SELECT st.name as studentName, co.description as courseDescription " +
03  "FROM Enrolment e " +
04  "INNER JOIN Student st on e.studentId=st.studentId " +
05  "INNER JOIN Course co on e.courseCode=co.courseCode")
06  .addScalar("studentName")
07  .addScalar("courseDescription")
08  .setResultTransformer( Transformers.aliasToBean(StudentDTO.class))
09  .list();
 
10

Tip: the addScalar() calls were required on HSQLDB to make it match a property name since it returns column names in all uppercase (e.g. "STUDENTNAME"). This could also be solved with a custom transformer that search the property names instead of using exact match - maybe we should provide a fuzzyAliasToBean() method ;

 

还有一种方式解决,就是使用双引号将别名包裹起来,感觉不是很优雅。像这样
 
1String sql = "select id as \"id\",iata as \"iata\",flight as \"flight\",dest as \"dest\",domint as \"domint\" " +  
2            " ,sdt as \"sdt\",task_nature as \"taskNature\",est_date as \"estDate\",act_date as \"actDate\",remark as \"remark\" " +  
3            " from FIDS_DEPF";


虽然提供的引用未涉及Spring Cloud中数据库属性与实体命名不一致的解决办法,但结合专业知识,通常可采用以下几种方式处理: ### 使用JPA注解 在JPA中,可通过`@Column`注解来指定数据库表的列名,从而解决属性与列名不一致的问题。示例代码如下: ```java import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; @Entity public class User { @Id private Long id; // 指定数据库列名为user_name @Column(name = "user_name") private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } } ``` 在上述代码中,实体类`User`的`name`属性对应数据库表中的`user_name`列。 ### 配置命名策略 可以通过配置JPA的命名策略,使实体属性名与数据库列名之间进行自动转换。例如,使用`PhysicalNamingStrategyStandardImpl`策略,它会直接使用实体属性名作为数据库列名。在`application.properties`中进行如下配置: ```properties spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl ``` ### 使用ResultTransformer 在使用Hibernate进行查询时,可以使用`ResultTransformer`将查询结果映射到实体对象,即使属性名与列名不一致也能正确映射。示例代码如下: ```java import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.criterion.Projections; import org.hibernate.transform.Transformers; import java.util.List; public class UserDao { public List<User> getUsers(Session session) { Criteria criteria = session.createCriteria(User.class); criteria.setProjection(Projections.projectionList() .add(Projections.property("id"), "id") .add(Projections.property("user_name"), "name")); criteria.setResultTransformer(Transformers.aliasToBean(User.class)); return criteria.list(); } } ``` 在上述代码中,通过`Projections`指定查询的列,并使用`Transformers.aliasToBean`将查询结果映射到`User`实体对象。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值