web-dev-qa-db-fra.com

Obtenir une erreur Impossible de localiser le constructeur approprié sur la classe

J'essaie de mapper le résultat SQL natif à mon POJO. Voici la configuration. J'utilise le printemps.

<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> 

Voici ma classe

@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

Voici comment je l'appelle

    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();

Mais quand il s'agit de ligne

List<CourseCompletion> courseCompletionList = query.getResultList();

Je reçois une erreur

Could not locate appropriate constructor on class : mypackage.CourseCompletion

Voici la requête que j'essaie

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

Pourquoi je reçois cette erreur?

Merci

22
Basit

Cette exception se produit car JPA ne modifie pas les types de colonnes renvoyés par la base de données pour les requêtes natives. Pour cette raison, vous avez une incompatibilité de type. Je ne sais pas quelle colonne provoque ce problème dans votre cas (cela dépend du SGBD que vous utilisez), mais je soupçonne que vous avez BigInteger dans le jeu de résultats au lieu de Integer pour colonne de score . Pour être sûr à 100%, ajoutez un point d'arrêt à ConstructorResultColumnProcessor.resolveConstructor(Class targetClass, List<Type> types) et examinez. Après avoir trouvé une incompatibilité, modifiez le type de champ dans votre classe de mappage.

Une autre solution sera de ne pas utiliser @SqlResultSetMapping du tout. Comme votre classe CourseCompletion est une entité gérée, vous devriez pouvoir lui mapper directement la requête native. Voir cette question pour plus d'informations.

65

Ajout d'un point d'arrêt au ConstructorResultColumnProcessor.resolveConstructor a fonctionné pour moi. Ma requête avait une sélection rowNum et elle est mappée en tant que type BigDecimal. J'avais le constructeur avec un BigInteger.

0
sevvalai