JPA with hibernate implementation is generating wrong named query

510 views Asked by At

I configured JPA with spring. I am using spring 4.

I have an entity

@Entity
@NamedQueries({
    @NamedQuery(name="PartnerCourseMapping.findByPartnerCourseIdAndHandlerName", query="select pm from PartnerCourseMapping pm where pm.partnerCourseId=:partnerCourseId and pm.handlerName=:handlerName")
})
@Table(name="PARTNER_COURSE_MAPPING")
public class PartnerCourseMapping implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    protected Long id;

    @Column(name="COURSE_ID")
    protected Long courseId;

    @Column(name="PARTNER_COURSE_ID")
    protected String partnerCourseId;

    @Column(name="PARTNER_ID")
    protected Integer partnerId;

    @Column(name="PRODUCT_TYPE")
    protected String productType;

    @Column(name="HANDLER_NAME")
    protected String handlerName;

    //getters and setters

}

I have another entity which i defined like below

@Entity
@NamedNativeQueries({
@NamedNativeQuery(
    name="ExternalCourse.findExternalCourseMappingByLearningSessionGuid",
    query="SELECT PCM.*, LE.id AS LearnerEnrollmentId, LE.LEARNER_ID AS LearnerId "
            + "FROM LEARNINGSESSION LS "
            + "INNER JOIN LEARNERENROLLMENT LE ON LE.ID = LS.ENROLLMENT_ID  "
            + "INNER JOIN PARTNER_COURSE_MAPPING PCM ON PCM.COURSE_ID = LE.COURSE_ID "
            + "WHERE LS.LEARNINGSESSIONGUID = :learningSessionGuid",
    resultSetMapping="externalCourseMapping"
    )
})

@SqlResultSetMappings({ 
@SqlResultSetMapping(
    name="externalCourseMapping", 
    classes = {
        @ConstructorResult(targetClass = ExternalCourse.class,
            columns={
                @ColumnResult(name = "ID", type=Long.class ),
                // remaing ColumnResult
            }
        )
    }
    )
})
public class ExternalCourse extends PartnerCourseMapping /*implements Serializable*/ {

    private Long learnerEnrollmentId;
    private Long learnerId;

   //default constructor

    public ExternalCourse(Long id, Long courseId, String partnerCourseId, Integer partnerId, String productType, 
        String handlerName, Long learnerEnrollmentId, Long learnerId) {

        this.id = id;
        // remaing values
    }

    //getters and setters for learnerEnrollmentId and learnerId

}

Now I query PartnerCourseMapping.findByPartnerCourseIdAndHandlerName

TypedQuery<PartnerCourseMapping> query = entityManager.createNamedQuery("PartnerCourseMapping.findByPartnerCourseIdAndHandlerName", PartnerCourseMapping.class);
query.setParameter("partnerCourseId", paernerCourseId);
query.setParameter("handlerName", handlerName);
return getResult(query);

protected T getResult(TypedQuery<T> query) {
    List<T> list = query.getResultList();
    return CollectionUtils.isEmpty(list) ? null : list.get(0);
}

Hibernate is generating exception that

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
...
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: Invalid column name 'learnerEnrollmentId'.

When I debug then I saw hibernate is generating query like below

select partnercou0_.id as id2_13_, 
  partnercou0_.COURSE_ID as COURSE_I3_13_, 
  partnercou0_.HANDLER_NAME as HANDLER_4_13_, 
  partnercou0_.PARTNER_COURSE_ID as PARTNER_5_13_, 
  partnercou0_.PARTNER_ID as PARTNER_6_13_, 
  partnercou0_.PRODUCT_TYPE as PRODUCT_7_13_, 
  partnercou0_.learnerEnrollmentId as learnerE8_13_, 
  partnercou0_.learnerId as learnerI9_13_, 
  partnercou0_.DTYPE as DTYPE1_13_ 
from PARTNER_COURSE_MAPPING partnercou0_ where partnercou0_.PARTNER_COURSE_ID=? and partnercou0_.HANDLER_NAME=?

I want to ask that why hibernate is including learnerEnrollmentId and learnerId column? I am passing the query name and query. If I refactor my code like below then I get the correct result

@Entity
@NamedNativeQueries({
    @NamedNativeQuery(
        name="ExternalCourse.findExternalCourseMappingByLearningSessionGuid",
        ...
        resultSetMapping="externalCourseMapping"
    )
})

@SqlResultSetMappings({ 
    @SqlResultSetMapping(
        name="externalCourseMapping", 
        classes = {
            ..
        }
    )
})
public class ExternalCourse implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    private Long id;
    private Long courseId;
    private String partnerCourseId;
    private Integer partnerId;
    private String productType;
    private String handlerName;
    private Long learnerEnrollmentId;
    private Long learnerId;

    //default constructor
    //constructor with all parameters
    //getters and setters
}

Why I am getting exception when I am extending class? I am passing the query name. Why ?

Thanks

0

There are 0 answers