27

我正在尝试将本机 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

为什么我收到此错误?

谢谢

4

4 回答 4

84

This exception happens because JPA doesn't change column types returned from the database for native queries. Because of this, you have type mismatch. I'm not sure about which column causes this problem in your case (this depends on DBMS you use), but I would suspect you have BigInteger in the result set instead of Integer for score column. To be 100% sure, add a breakpoint to ConstructorResultColumnProcessor.resolveConstructor(Class targetClass, List<Type> types) and investigate. After you find a mismatch, change field type in your mapping class.

Another solution will be not to use @SqlResultSetMapping at all. As your CourseCompletion class is a managed entity, you should be able to map native query to it directly. See this question for more information.

于 2014-07-14T09:28:59.040 回答
2

为我工作的工作添加一个断点ConstructorResultColumnProcessor.resolveConstructor。我的查询有一个rowNum选择,它被映射为BigDecimal类型。我的构造函数带有BigInteger.

于 2019-12-05T17:21:36.140 回答
0

这发生在我身上,因为出于某种原因,我将构造函数指定为私有的。断点帮助了我,ConstructorResultColumnProcessor.resolveConstructor因为我意识到它从未找到我的构造函数。

于 2021-11-19T18:28:13.647 回答
0

谢谢。向 ConstructorResultColumnProcessor.resolveConstructor 方法添加了调试点。Hibernate 结果类型为 BigIntegerType,DTO 对象返回类型为 Integer。所以 allMatched 标志是假的。这就是为什么它会抛出“无法在类上找到适当的构造函数”谢谢 Ram

于 2020-12-21T20:04:34.517 回答