我正在尝试将原生SQL结果映射到我的POJO。这是配置。我正在使用春天。
<bean id="ls360Emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >
<property name="dataSource" ref="ls360DataSource" />
<property name="jpaVendorAdapter" ref="vendorAdaptor" />
<property name="packagesToScan" value="abc.xyz"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.max_fetch_depth">3</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.jdbc.batch_size">10</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
这是我的班级
@SqlResultSetMapping(
name="courseCompletionMapping",
classes = {
@ConstructorResult(targetClass = CourseCompletion.class,
columns={
@ColumnResult(name = "StoreId", type = String.class),
@ColumnResult(name = "ProductId", type = String.class),
@ColumnResult(name = "UserName", type = String.class),
@ColumnResult(name = "Score", type = Integer.class),
@ColumnResult(name = "CompletionDate", type = Date.class)
}
)
}
)
@Entity
public class CourseCompletion {
private String storeId;
@Id
private String productId;
private String userName;
private int score;
private Date completionDate;
public CourseCompletion() {
}
public CourseCompletion(String storeId, String productId, String userName, int score, Date completionDate) {
this.storeId = storeId;
this.productId = productId;
this.userName = userName;
this.score = score;
this.completionDate = completionDate;
}
// getters and setters
这就是我如何称呼它
Properties coursePropertiesFile = SpringUtil.loadPropertiesFileFromClassPath("course.properties");
String queryString = coursePropertiesFile.getProperty("course.completion.sql");
long distributorId = 1;
String fromDate = "2009-09-22 00:00:00";
String toDate = "2014-04-11 23:59:59";
Query query = em.createNativeQuery(queryString, "courseCompletionMapping");
//Query query = em.createNamedQuery("findAllEmployeeDetails");
query.setParameter("distributorId", distributorId);
query.setParameter("fromDate", fromDate);
query.setParameter("toDate", toDate);
@SuppressWarnings("unchecked")
List<CourseCompletion> courseCompletionList = query.getResultList();
但是当涉及到行
List<CourseCompletion> courseCompletionList = query.getResultList();
我收到错误
Could not locate appropriate constructor on class : mypackage.CourseCompletion
这是我正在尝试的查询
select d.DISTRIBUTORCODE AS StoreId, u.USERGUID AS ProductId, u.UserName,
lcs.HIGHESTPOSTTESTSCORE AS Score, lcs.CompletionDate
from VU360User u
inner join learner l on u.ID = l.VU360USER_ID
inner join LEARNERENROLLMENT le on le.LEARNER_ID = l.ID
inner join LEARNERCOURSESTATISTICS lcs on lcs.LEARNERENROLLMENT_ID = le.ID
inner join customer c on c.ID = l.CUSTOMER_ID
inner join DISTRIBUTOR d on d.ID = c.DISTRIBUTOR_ID
where d.ID = :distributorId
and lcs.COMPLETIONDATE is not null
and (lcs.COMPLETIONDATE between :fromDate and :toDate)
and lcs.COMPLETED = 1
为什么我收到此错误?
由于
答案 0 :(得分:58)
发生此异常是因为JPA不会更改从数据库返回的本机查询的列类型。因此,您的类型不匹配。我不确定哪个列会导致您出现此问题(这取决于您使用的DBMS),但我怀疑您在结果集中有BigInteger
而不是Integer
用于得分列。要100%确定,请向ConstructorResultColumnProcessor.resolveConstructor(Class targetClass, List<Type> types)
添加断点并进行调查。找到不匹配项后,请在映射类中更改字段类型。
另一种解决方案是根本不使用@SqlResultSetMapping
。由于您的CourseCompletion
类是托管实体,因此您应该能够直接将本机查询映射到它。有关详细信息,请参阅this question。
答案 1 :(得分:0)
为ConstructorResultColumnProcessor.resolveConstructor
添加一个断点对我来说很有效。我的查询选择了rowNum
,并且已映射为BigDecimal
类型。我有一个BigInteger
的构造函数。
答案 2 :(得分:0)
谢谢。向 ConstructorResultColumnProcessor.resolveConstructor 方法添加了调试点。 Hibernate 结果类型为 BigIntegerType,DTO 对象返回类型为 Integer。所以 allMatched 标志是假的。这就是为什么它抛出“无法在类上找到合适的构造函数”的原因 谢谢 拉姆