休眠查询无法解析 属性,即使 属性 存在且大小写正确

hibernate query could not resolve property even if the property is there and correct casing

大家好!

我有一种方法可以用来查找与 CourseRevision 相关的 Admission 列表,但它似乎无法识别 CourseRevision,即使它在实体 class 中也是如此。这是查找录取的代码:

public List<AdmissionDTO> findAdmissions(final String searchPhrase, final String organisationId, final boolean useCourse, final boolean useAdmissionAlternatives, final boolean useApplicationStatusMap, final boolean useTeaching, final boolean useAdmissionSchemaSettings, final boolean useAdmissionSchemaUpload) throws DataAccessException {
    logEntered();
    List<AdmissionDTO> resultsList = new ArrayList<AdmissionDTO>();
if (organisationId == null) {
    log.warn("'organisationId' is NULL or empty!");
    return resultsList;
}

resultsList = new DTOListFetcher<AdmissionDTO, Admission>() {
    @Override
    protected Map<String, Object> getParameters() {
        Map<String, Object> params = new HashMap<String, Object>();
        if (searchPhrase != null && searchPhrase.length() > 0) {
            params.put("searchPhrase", MessageFormat.format("%{0}%", searchPhrase));
        }
        params.put("organisationId", organisationId);
        return params;
    }

    @Override
    protected String getQueryString() {
        String queryString = "from Admission a " + "left join fetch a.courseRevision cr "
                + "left join fetch cr.course c " + "left join fetch c.courseDefinition "
                + "left join fetch a.admissionAlternatives " + "left join fetch a.applications "
                + "left join fetch a.teaching " + "left join fetch a.admissionSchemaSettings "
                + "left join fetch a.admissionSchemaUploads " + "where a.organisationId in (select o.id from Organisation o where o.parentOrganisationId = :organisationId) ";
        StringBuilder sb = new StringBuilder(queryString);
        if (searchPhrase != null && searchPhrase.length() > 0) {
            sb.append(" AND (");
            sb.append("lower(a.courseRevision.course.code) like lower(:searchPhrase)");
            sb.append(" OR lower(a.name) like lower(:searchPhrase)");
            sb.append(" OR lower(a.courseRevision.name) like lower(:searchPhrase)");
            sb.append(")");

        }
        return sb.toString();
    }

    @Override
    protected AdmissionDTO createDTO(Admission bean) {
        return new AdmissionDTO(bean, useCourse, useAdmissionAlternatives, useApplicationStatusMap, useTeaching,
                useAdmissionSchemaSettings, useAdmissionSchemaUpload);
    }

    @Override
    protected ResultTransformer getQueryResultTransformer() {
        return Criteria.DISTINCT_ROOT_ENTITY;
    }
}.fetchList();

if (resultsList == null) {
    throw new DataAccessException(
            "DataManager: an error has occurred while trying to find Admission objects in database!");
}
logReturning(resultsList);
return resultsList;
}

这是我的 DTOListFetcher:

public abstract class DTOListFetcher<DTO, E> {

    private static final Log log = LogFactory.getLog(DTOListFetcher.class);

    /**
     * Return a map of parameters used for the hibernate query for this
     * {@code DTOListFetcher}. Parameters in the map are identified by parameter
     * name of {@code String} type. Parameter value can be any object or array
     * of objects.
     *
     * @return a map with query parameters.
     */
    protected abstract Map<String, Object> getParameters();

    /**
     * Returns query string for this {@code DTOListFetcher} implementation.
     *
     * @return a hibernate query string.
     */
    protected abstract String getQueryString();

    /**
     * Method to create a DTO object from the provided entity object.
     *
     * @param object - an entity object from which the resulting DTO object will
     * be created.
     * @return a DTO object.
     */
    protected abstract DTO createDTO(E object);

    /**
     * Empty implementation. Sublasses can override this method to apply extra
     * actions for the DTO object.
     *
     * @param session - reference to the current session.
     * @param item - entity item.
     * @param dto - DTO object to update.
     */
    protected void applyExtras(Session session, E item, DTO dto) {
    }

    /**
     * The main public method of the class. It Implements basic algorithm for
     * fetching list of items from the database. It calls some abstract methods
     * that require specific logic which is implemented in extending classes.
     *
     * @return a list of {@code DTO} objects.
     */
    public List<DTO> fetchList() {
        logEntered();
        Transaction tx = null;
        Session session = HibernateUtil.getSession();
        List<DTO> resultList = null;
        try {
            tx = session.beginTransaction();
            String queryString = getQueryString();
            Query query = session.createQuery(queryString);

            ResultTransformer resultTransformer = getQueryResultTransformer();
            if (resultTransformer != null) {
                query.setResultTransformer(resultTransformer);
            }

            Map<String, Object> parametersMap = getParameters();
            if (parametersMap != null && !parametersMap.isEmpty()) {
                for (String key : parametersMap.keySet()) {
                    Object param = parametersMap.get(key);
                    if (param instanceof Object[]) {
                        query.setParameterList(key, (Object[]) param);
                    }
                    else {
                        query.setParameter(key, param);
                    }
                }
            }
            List<E> results = query.list();
            if (results != null) {
                resultList = new ArrayList<DTO>();
                for (E item : results) {
                    DTO dto = createDTO(item);
                    applyExtras(session, item, dto);
                    resultList.add(dto);
                }
            } else {
                log.warn("The query returned NULL!");
            }
            commit(tx);
        } catch (Exception e) {
            handleException(e, tx);
            // Returned result will be NULL if error occurs!
            resultList = null;
        } finally {
            HibernateUtil.closeSession(session);
        }
        logReturning(resultList);
        return resultList;
    }

    private void logEntered() {
        log.info(MessageFormat.format("{0}: entered method ''{1}()''", this.getClass().getSimpleName(), getMethodName()));
    }

    /**
     * Get the method name for a depth in call stack. <br /> Utility function
     *
     * @param depth depth in the call stack (0 means current method, 1 means
     * call method, ...)
     * @return method name
     */
    private static String getMethodName() {
        final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
        return ste[3].getMethodName(); //Thank you Tom Tresansky
    }

    private void commit(Transaction tx) {
        if (tx != null) {
            log.info("Committing transaction...");
            tx.commit();
            log.info("Transaction successfully commited.");
        }
    }

    private void handleException(Exception e, Transaction tx) {
        e.printStackTrace();
        if (tx != null) {
            log.info("rolling back transaction");
            tx.rollback();
            log.info("transaction successfully rolled back");
        }
    }

    public void logReturning(Object o) {
        String returnObject = o != null ? o.getClass().getSimpleName() : null;
        if (returnObject != null && o instanceof List) {
            if (((List) o).size() > 0) {
                returnObject = MessageFormat.format("{0}<{1}>", returnObject, ((List) o).get(0).getClass().getSimpleName());
            }
            returnObject = returnObject + ", total entries: " + ((List) o).size();
        }
        String className = this.getClass().getSimpleName();
        log.info(MessageFormat.format("{0}: returning from ''{1}()'' with result of type: {2}", className, getMethodName(), returnObject));
    }

    protected ResultTransformer getQueryResultTransformer() {
        return null;
    }
}

录取实体class:

@NamedQueries({ @NamedQuery(name = "getOngoingAdmissions", query = "from Admission a "
        + "where a.openingDate <= :referenceDate " + "and a.closingDate >= :referenceDate "
        + "and a.organisationId = :organisationId " + "order by a.openingDate") })
@Entity
@Table(name = "ADMISSION", schema = "SOACOURSE")
public class Admission implements Serializable {

    public static final String ADMISSION_TYPE_MANATT = "MANATT";
    public static final String ADMISSION_TYPE_DIRATT = "DIRATT";
    /*
     * Column names.
     */
    public static final String COLUMN_ID = "ID";
    public static final String COLUMN_ORGANISATION_ID = "ORGANISATION_ID";

    public static final String QUERY_ONGOING_ADMISSIONS = "getOngoingAdmissions";
    public static final String PARAM_REFERENCE_DATE = "referenceDate";
    public static final String PARAM_ORGANISATION_ID = "organisationId";
    public static final String PARAM_ID = "id";
    private static final long serialVersionUID = 995596202971143170L;
    /*
     * Attributes.
     */
    private String id;
    private String courseId;
    private int revisionNr;
    // private CourseExtended courseExtended;
    private CourseRevision courseRevision;
    private String name;
    private String admissionTypeCode;
    private String description;
    private Integer admissionType;
    private Date openingDate;
    private Date closingDate;
    private short publish;
    private Date publishOpeningDate;
    private Date publishClosingDate;
    private Integer admissionOfferValidSlot;
    private Integer admissionOfferSlotSlack;
    private String infoLink;
    private short emailVerification;
    private short emailAttachment;
    private String emailReply;
    private String emailSubject;
    private String emailContent;
    private Boolean responseRequired;
    private String information;
    private String helpLink;
    private short publishSelfService;
    private Integer ceiling;
    private String organisationId;
    private String productNumber;
    private Teaching teaching;
    private Set<AdmissionEmailDocument> admissionEmailDocuments = new HashSet<AdmissionEmailDocument>(0);
    private Set<Application> applications = new HashSet<Application>(0);
    private Set<AdmissionSurvey> admissionSurveys = new HashSet<AdmissionSurvey>(0);
    private Set<AdmissionAlternative> admissionAlternatives = new HashSet<AdmissionAlternative>(0);
    private Set<AdmissionArticle> admissionArticles = new HashSet<AdmissionArticle>(0);
    private AdmissionSchemaSettings admissionSchemaSettings;
    private Set<AdmissionSchemaUpload> admissionSchemaUploads = new HashSet<AdmissionSchemaUpload>(0);
    private List<AdmissionEmail> admissionEmails = new ArrayList<AdmissionEmail>(0);
    private Organisation organisation;

    // private Set<AdmissionTeaching> admissionTeachings = new HashSet<AdmissionTeaching>(0);
    public Admission() {}

    @Id
    @Column(name = "ID", unique = true, nullable = false, length = 28)
    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Column(name = "COURSE_ID", nullable = false, length = 28)
    public String getCourseId() {
        return courseId;
    }

    public void setCourseId(String courseId) {
        this.courseId = courseId;
    }

    @Column(name = "REVISION_NR", nullable = false, precision = 3)
    public int getRevisionNr() {
        return revisionNr;
    }

    public void setRevisionNr(int revisionNr) {
        this.revisionNr = revisionNr;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "TEACHING_ID")
    public Teaching getTeaching() {
        return this.teaching;
    }

    public void setTeaching(Teaching teaching) {
        this.teaching = teaching;
    }

    @Column(name = "NAME", nullable = false, length = 250)
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "ADMISSION_TYPE_CODE", nullable = false, length = 8)
    public String getAdmissionTypeCode() {
        return this.admissionTypeCode;
    }

    public void setAdmissionTypeCode(String admissionTypeCode) {
        this.admissionTypeCode = admissionTypeCode != null ? admissionTypeCode : "DIRATT";
    }

    @Column(name = "DESCRIPTION", length = 2000)
    public String getDescription() {
        return this.description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Column(name = "ADMISSION_TYPE", precision = 1, scale = 0)
    public Integer getAdmissionType() {
        return this.admissionType;
    }

    public void setAdmissionType(Integer admissionType) {
        this.admissionType = admissionType;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "OPENING_DATE", length = 7)
    public Date getOpeningDate() {
        return this.openingDate;
    }

    public void setOpeningDate(Date openingDate) {
        this.openingDate = openingDate;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "CLOSING_DATE", length = 7)
    public Date getClosingDate() {
        return this.closingDate;
    }

    public void setClosingDate(Date closingDate) {
        this.closingDate = closingDate;
    }

    @Column(name = "PUBLISH", nullable = false, precision = 1, scale = 0)
    public short getPublish() {
        return this.publish;
    }

    public void setPublish(Short publish) {
        this.publish = publish != null ? publish : 0;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "PUBLISH_OPENING_DATE", length = 7)
    public Date getPublishOpeningDate() {
        return this.publishOpeningDate;
    }

    public void setPublishOpeningDate(Date publishOpeningDate) {
        this.publishOpeningDate = publishOpeningDate;
    }

    @Temporal(TemporalType.DATE)
    @Column(name = "PUBLISH_CLOSING_DATE", length = 7)
    public Date getPublishClosingDate() {
        return this.publishClosingDate;
    }

    public void setPublishClosingDate(Date publishClosingDate) {
        this.publishClosingDate = publishClosingDate;
    }

    @Column(name = "ADMISSION_OFFER_VALID_SLOT", precision = 2, scale = 0)
    public Integer getAdmissionOfferValidSlot() {
        return this.admissionOfferValidSlot;
    }

    public void setAdmissionOfferValidSlot(Integer admissionOfferValidSlot) {
        this.admissionOfferValidSlot = admissionOfferValidSlot;
    }

    @Column(name = "ADMISSION_OFFER_SLOT_SLACK", precision = 2, scale = 0)
    public Integer getAdmissionOfferSlotSlack() {
        return this.admissionOfferSlotSlack;
    }

    public void setAdmissionOfferSlotSlack(Integer admissionOfferSlotSlack) {
        this.admissionOfferSlotSlack = admissionOfferSlotSlack;
    }

    @Column(name = "INFO_LINK")
    public String getInfoLink() {
        return this.infoLink;
    }

    public void setInfoLink(String infoLink) {
        this.infoLink = infoLink;
    }

    @Column(name = "EMAIL_VERIFICATION", nullable = false, precision = 1, scale = 0)
    public short getEmailVerification() {
        return this.emailVerification;
    }

    public void setEmailVerification(Short emailVerification) {
        this.emailVerification = emailVerification != null ? emailVerification : 0;
    }

    @Column(name = "EMAIL_ATTACHMENT", nullable = false, precision = 1, scale = 0)
    public short getEmailAttachment() {
        return this.emailAttachment;
    }

    public void setEmailAttachment(Short emailAttachment) {
        this.emailAttachment = emailAttachment != null ? emailAttachment : 0;
    }

    @Column(name = "EMAIL_REPLY")
    public String getEmailReply() {
        return this.emailReply;
    }

    public void setEmailReply(String emailReply) {
        this.emailReply = emailReply;
    }

    @Column(name = "EMAIL_SUBJECT")
    public String getEmailSubject() {
        return this.emailSubject;
    }

    public void setEmailSubject(String emailSubject) {
        this.emailSubject = emailSubject;
    }

    @Column(name = "EMAIL_CONTENT", length = 2000)
    public String getEmailContent() {
        return this.emailContent;
    }

    public void setEmailContent(String emailContent) {
        this.emailContent = emailContent;
    }

    @Column(name = "RESPONSE_REQUIRED", precision = 1, scale = 0)
    public Boolean getResponseRequired() {
        return this.responseRequired;
    }

    public void setResponseRequired(Boolean responseRequired) {
        this.responseRequired = responseRequired;
    }

    @Column(name = "INFORMATION", length = 2000)
    public String getInformation() {
        return this.information;
    }

    public void setInformation(String information) {
        this.information = information;
    }

    @Column(name = "HELP_LINK")
    public String getHelpLink() {
        return this.helpLink;
    }

    public void setHelpLink(String helpLink) {
        this.helpLink = helpLink;
    }

    @Column(name = "PUBLISH_SELF_SERVICE", nullable = false, precision = 1, scale = 0)
    public short getPublishSelfService() {
        return this.publishSelfService;
    }

    public void setPublishSelfService(Short publishSelfService) {
        this.publishSelfService = publishSelfService != null ? publishSelfService : 0;
    }

    @Column(name = "CEILING", precision = 4, scale = 0)
    public Integer getCeiling() {
        return this.ceiling;
    }

    public void setCeiling(Integer ceiling) {
        this.ceiling = ceiling;
    }

    @Column(name = "ORGANISATION_ID", length = 28)
    public String getOrganisationId() {
        return this.organisationId;
    }

    public void setOrganisationId(String organisationId) {
        this.organisationId = organisationId;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    public Set<AdmissionEmailDocument> getAdmissionEmailDocuments() {
        return this.admissionEmailDocuments;
    }

    public void setAdmissionEmailDocuments(Set<AdmissionEmailDocument> admissionEmailDocuments) {
        this.admissionEmailDocuments = admissionEmailDocuments;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    public Set<Application> getApplications() {
        return this.applications;
    }

    public void setApplications(Set<Application> applications) {
        this.applications = applications;
    }

    // @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    // public Set<AdmissionTeaching> getAdmissionTeachings() {
    // return this.admissionTeachings;
    // }
    //
    // public void setAdmissionTeachings(Set<AdmissionTeaching> admissionTeachings) {
    // this.admissionTeachings = admissionTeachings;
    // }
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    public Set<AdmissionSurvey> getAdmissionSurveys() {
        return this.admissionSurveys;
    }

    public void setAdmissionSurveys(Set<AdmissionSurvey> admissionSurveys) {
        this.admissionSurveys = admissionSurveys;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    @OrderBy(AdmissionAlternative.PROPERTY_SORT_ORDER + " ASC")
    public Set<AdmissionAlternative> getAdmissionAlternatives() {
        return this.admissionAlternatives;
    }

    public void setAdmissionAlternatives(Set<AdmissionAlternative> admissionAlternatives) {
        this.admissionAlternatives = admissionAlternatives;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    public Set<AdmissionArticle> getAdmissionArticles() {
        return this.admissionArticles;
    }

    public void setAdmissionArticles(Set<AdmissionArticle> admissionArticles) {
        this.admissionArticles = admissionArticles;
    }

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "admission")
    public AdmissionSchemaSettings getAdmissionSchemaSettings() {
        return this.admissionSchemaSettings;
    }

    public void setAdmissionSchemaSettings(AdmissionSchemaSettings admissionSchemaSettings) {
        this.admissionSchemaSettings = admissionSchemaSettings;
    }

    // @ManyToOne(fetch = FetchType.LAZY)
    // @JoinColumns({
    // @JoinColumn(name = "COURSE_ID", referencedColumnName = "COURSE_ID", insertable = false,
    // updatable = false),
    // @JoinColumn(name = "REVISION_NR", referencedColumnName = "REVISION_NR", insertable = false,
    // updatable = false)
    // })
    // public CourseExtended getCourseExtended() {
    // return this.courseExtended;
    // }
    //
    // public void setCourseExtended(CourseExtended courseExtended) {
    // this.courseExtended = courseExtended;
    // }
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumns({
            @JoinColumn(name = "COURSE_ID", referencedColumnName = "COURSE_ID", nullable = false, insertable = false, updatable = false),
            @JoinColumn(name = "REVISION_NR", referencedColumnName = "REVISION_NR", nullable = false, insertable = false, updatable = false) })
    public CourseRevision getCourseRevision() {
        return this.courseRevision;
    }

    public void setCourseRevision(CourseRevision courseRevision) {
        this.courseRevision = courseRevision;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "admission")
    public Set<AdmissionSchemaUpload> getAdmissionSchemaUploads() {
        return admissionSchemaUploads;
    }

    public void setAdmissionSchemaUploads(Set<AdmissionSchemaUpload> admissionSchemaUploads) {
        this.admissionSchemaUploads = admissionSchemaUploads;
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = AdmissionEmail.PROPERTY_ADMISSION)
    public List<AdmissionEmail> getAdmissionEmails() {
        return admissionEmails;
    }

    public void setAdmissionEmails(List<AdmissionEmail> admissionEmails) {
        this.admissionEmails = admissionEmails;
    }

    @Transient
    public boolean isDiratt() {
        return ADMISSION_TYPE_DIRATT.equals(admissionTypeCode);
    }

    @Transient
    public boolean isManatt() {
        return ADMISSION_TYPE_MANATT.equals(admissionTypeCode);
    }

    @Column(name = "PRODUCT_NUMBER", length = 32)
    public String getProductNumber() {
        return productNumber;
    }

    public void setProductNumber(String productNumber) {
        this.productNumber = productNumber;
    }

    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = COLUMN_ORGANISATION_ID, referencedColumnName = Organisation.COLUMN_ADDRESS_OWNER_ID, insertable = false, updatable = false)
    public Organisation getOrganisation() {
        return organisation;
    }

    public void setOrganisation(Organisation organisation) {
        this.organisation = organisation;
    }
}

我不知道为什么当外壳正确时它会失败。或者我可能忽略了一些东西。我希望有人能帮帮忙。

谢谢!

EDIT

我忘了说它在最近几个版本中有效,昨天有效但今天无效。

这个看起来有问题

sb.append("lower(a.courseRevision.course.code) like lower(:searchPhrase)");

您不能使用 a.courseRevision.course.code,因为您没有 a.courseRevision 别名。

也许 c.code