select firstName, lastName from Employee
query.setResultTransformer(Transformers.aliasToBean(MyResults.class));
Bạn có thể không sử dụng mã trên với Hibernate 5 và Hibernate 4 (ít nhất là Hibernate 4.3.6.Final), vì ngoại lệ
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)
Vấn đề là Hibernate chuyển đổi bí danh cho tên cột thành chữ thường - firstName
trở thành FIRSTNAME
. Và nó cố gắng tìm một getter với tên getFIRSTNAME()
, và setter setFIRSTNAME()
trong DTO
sử dụng chiến lược như vậy
PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl(
PropertyAccessStrategyBasicImpl.INSTANCE,
PropertyAccessStrategyFieldImpl.INSTANCE,
PropertyAccessStrategyMapImpl.INSTANCE
);
Chỉ PropertyAccessStrategyMapImpl.INSTANCE
phù hợp, theo ý kiến của Hibernate, tốt. Vì vậy, sau đó nó sẽ cố gắng chuyển đổi (Map)MyResults
.
public void set(Object target, Object value, SessionFactoryImplementor factory) {
((Map) target).put(propertyName, value);
}
Không biết, đó là lỗi hoặc tính năng.
Làm thế nào để giải quyết
Sử dụng bí danh với dấu ngoặc kép
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();
Sử dụng một máy biến áp kết quả tùy chỉnh
Một cách khác để giải quyết vấn đề - sử dụng một máy biến áp kết quả mà bỏ qua trường hợp tên phương thức (xử lý getFirstName()
là getFIRSTNAME()
). Bạn có thể viết của riêng bạn hoặc sử dụng FluentHibernateResultTransformer. Bạn sẽ không cần phải sử dụng dấu ngoặc kép và bí danh (nếu bạn có tên cột bằng tên DTO).
Chỉ cần tải xuống thư viện từ trang dự án (không cần thêm lọ): fluent-hibernate.
String sql = "select firstName, lastName from Employee";
List<Results> employees = session.createSQLQuery(sql)
.setResultTransformer(new FluentHibernateResultTransformer(Results.class))
.list();
biến này có thể được sử dụng để dự báo lồng nhau quá: How to transform a flat result set using Hibernate
Funny, tôi có thể tạo lại vấn đề với Hibernate 5.1. Biến áp 'Transformers.aliasToBean (CatDTO.class)' không hoạt động. Tôi chỉ cần thử nghiệm với biến áp của riêng tôi trước khi :) Cố gắng tìm ra lý do tại sao như vậy. –
Thật buồn cười, tôi đã đúng với các bí danh. Xem câu trả lời của tôi: http://stackoverflow.com/a/37423885/3405171 –