为什么我在这个Spring项目中获得与命名查询相关的HibernateException?

时间:2014-12-29 15:34:13

标签: java sql spring hibernate

我在Hibernate和Spring开发方面绝对是新的,我有以下问题

我有一个名为KM_ProjectInfoStatus的实体类映射名为KM_PROJECT_INFO_STATUS的数据库表,所以我有这个类:

package egp.prc.km.model;

import javax.persistence.*;
import java.io.Serializable;

@NamedQueries({
        @NamedQuery(name = "kmProjectInfoStatusList", query = "select status from KM_PROJECT_INFO_STATUS status order by status.idProjectInfoStatus") ,
        @NamedQuery(name = "kmProjectInfoStatusById", query = "SELECT status FROM KM_PROJECT_INFO_STATUS status where lower(status.idProjectInfoStatus) = :statusId")
})

@Entity
@Table(name = "KM_PROJECT_INFO_STATUS")
public class KM_ProjectInfoStatus implements Serializable {

    @Id
    @GeneratedValue
    private Long idProjectInfoStatus;

    @Column(name = "foldertech")
    private Long foldertech;

    @Column(name = "folderproject")
    private Long folderproject;

    public Long getIdProjectInfoStatus() {
        return idProjectInfoStatus;
    }

    public void setIdProjectInfoStatus(Long idProjectInfoStatus) {
        this.idProjectInfoStatus = idProjectInfoStatus;
    }

    public Long getFoldertech() {
        return foldertech;
    }

    public void setFoldertech(Long foldertech) {
        this.foldertech = foldertech;
    }

    public Long getFolderproject() {
        return folderproject;
    }

    public void setFolderproject(Long folderproject) {
        this.folderproject = folderproject;
    }
}

正如您在上一个代码段中看到的那样,该类定义了2个命名查询,这些:

@NamedQueries({
        @NamedQuery(name = "kmProjectInfoStatusList", query = "select status from KM_PROJECT_INFO_STATUS status order by status.idProjectInfoStatus") ,
        @NamedQuery(name = "kmProjectInfoStatusById", query = "SELECT status FROM KM_PROJECT_INFO_STATUS status where lower(status.idProjectInfoStatus) = :statusId")
})

1)第一个名为 kmProjectInfoStatusList ,并从我的 KM_PROJECT_INFO_STATUS 表格中选择行列表。

2)第二个名为 kmProjectInfoStatusById ,并使用where条件中的id从我的 KM_PROJECT_INFO_STATUS 表中选择一行。

然后我必须实现一个实现DAO的Spring服务。

所以我首先创建一个名为 KMProjectInfoStatusService 的接口,其中我声明了我的DAO的方法:

public interface KMProjectInfoStatusService {

    @Transactional
    public List<KM_ProjectInfoStatus> getProjectInfoStatusList();

    @Transactional
    public KM_ProjectInfoStatus getProjectInfoStatus(Long idProjectInfoStatus);
}

我在Hibernate和Spring开发方面绝对是新的,我有以下问题

我有一个名为KM_ProjectInfoStatus的实体类映射名为KM_PROJECT_INFO_STATUS的数据库表,所以我有这个类:

package egp.prc.km.model;

import javax.persistence.*;
import java.io.Serializable;

@NamedQueries({
        @NamedQuery(name = "kmProjectInfoStatusList", query = "select status from KM_PROJECT_INFO_STATUS status order by status.name") ,
        @NamedQuery(name = "kmProjectInfoStatusById", query = "SELECT status  FROM KM_PROJECT_INFO_STATUS status  where lower(status.idProjectInfoStatus) = :statusId")
})

@Entity
@Table(name = "KM_PROJECT_INFO_STATUS")
public class KM_ProjectInfoStatus implements Serializable {

    @Id
    @GeneratedValue
    private Long idProjectInfoStatus;

    @Column(name = "foldertech")
    private Long foldertech;

    @Column(name = "folderproject")
    private Long folderproject;

    public Long getIdProjectInfoStatus() {
        return idProjectInfoStatus;
    }

    public void setIdProjectInfoStatus(Long idProjectInfoStatus) {
        this.idProjectInfoStatus = idProjectInfoStatus;
    }

    public Long getFoldertech() {
        return foldertech;
    }

    public void setFoldertech(Long foldertech) {
        this.foldertech = foldertech;
    }

    public Long getFolderproject() {
        return folderproject;
    }

    public void setFolderproject(Long folderproject) {
        this.folderproject = folderproject;
    }
}

正如您在上一个代码段中所看到的,该类还包含2个命名查询,这些查询:

@NamedQueries({
        @NamedQuery(name = "kmProjectInfoStatusList", query = "select status from KM_PROJECT_INFO_STATUS status order by status.name") ,
        @NamedQuery(name = "kmProjectInfoStatusById", query = "SELECT status  FROM KM_PROJECT_INFO_STATUS status  where lower(status.idProjectInfoStatus) = :statusId")
})

然后我必须实现一个实现DAO的Spring服务。

所以我首先创建一个名为KMProjectInfoStatusService的接口,在其中我声明了我的DAO的方法:

public interface KMProjectInfoStatusService {

@Transactional
public List<KM_ProjectInfoStatus> getProjectInfoStatusList();

@Transactional
public KM_ProjectInfoStatus getProjectInfoStatus(Long idProjectInfoStatus);

}

最后,我创建了 KMProjectInfoStatusServiceImp 类,它实现了以前的接口,代表了我的具体DAO:

@Repository("kmProjectInfoStatusService")
public class KMProjectInfoStatusServiceImpl extends AbstractService implements KMProjectInfoStatusService {

    public List<KM_ProjectInfoStatus> getProjectInfoStatusList() {
        //return new KM_ProjectInfoStatus[0];  //To change body of implemented methods use File | Settings | File Templates.

        return getHibernateTemplate().execute(
                new HibernateCallback<List<KM_ProjectInfoStatus>>() {
                    public List<KM_ProjectInfoStatus> doInHibernate(Session session) throws HibernateException, SQLException {
                        return getStatusList(session);
                    }
                }
        );
    }


    public KM_ProjectInfoStatus getProjectInfoStatus(Long idProjectInfoStatus) {
        //return null;  //To change body of implemented methods use File | Settings | File Templates.

        final Long id = idProjectInfoStatus;
        return getHibernateTemplate().execute(
                new HibernateCallback<KM_ProjectInfoStatus>() {
                    public KM_ProjectInfoStatus doInHibernate(Session session) throws HibernateException, SQLException {
                        return getStatus(id, session);
                    }
                }
        );
    }

    private List<KM_ProjectInfoStatus> getStatusList(Session session) {
        //create query:
        Query query = session.getNamedQuery("kmProjectInfoStatusList");
        List<KM_ProjectInfoStatus> statusList =  query.list();

        return statusList;
    }

    private KM_ProjectInfoStatus getStatus(Long idProjectInfoStatus, Session session) {
        //create query:
        Query query = session.getNamedQuery("kmProjectInfoStatusById");
        query.setParameter("statusId", idProjectInfoStatus);

        KM_ProjectInfoStatus status = (KM_ProjectInfoStatus) query.uniqueResult();

        return status;
    }
}

正如您在本课程中看到的,我实现了在接口中声明的2个方法 getProjectInfoStatusList() getProjectInfoStatus()。这两种方法分别使用 getStatusList()来执行第一个命名查询以获取列表,使用 getStatus()执行第二个查询以从其id获取对象。

问题是,当我尝试执行我的项目时, HibernateException 是throwns,我在stacktrace中获得以下错误消息:

2014-12-29 16:25:44,210 [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR impl.SessionFactoryImpl.<init>(363) - Error in named query: kmProjectInfoStatusById
org.hibernate.hql.ast.QuerySyntaxException: KM_PROJECT_INFO_STATUS is not mapped [SELECT status  FROM KM_PROJECT_INFO_STATUS status  where lower(status.idProjectInfoStatus) = :statusId]
    at org.hibernate.hql.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:158)
    at org.hibernate.hql.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:87)
    at org.hibernate.hql.ast.tree.FromClause.addFromElement(FromClause.java:70)
    at org.hibernate.hql.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:255)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3056)
    at org.hibernate.hql.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:2945)
    ................................................................................
    ................................................................................
    ................................................................................
    ................................................................................
<29-dic-2014 16.25.44 CET> <Error> <Deployer> <BEA-149202> <Encountered an exception while attempting to commit the 1 task for the application 'KM_Web_war_exploded'.> 
<29-dic-2014 16.25.44 CET> <Warning> <Deployer> <BEA-149004> <Failures were detected while initiating deploy task for application 'KM_Web_war_exploded'.> 
<29-dic-2014 16.25.44 CET> <Warning> <Deployer> <BEA-149078> <Stack trace for message 149004
weblogic.application.ModuleException: :org.hibernate.HibernateException:Errors in named queries: kmProjectInfoStatusById, kmProjectInfoStatusList
    at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:365)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1300)
    at org.hibernate.cfg.AnnotationConfiguration.buildSessionFactory(AnnotationConfiguration.java:859)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:860)
    at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:779)
    Truncated. see log file for complete stacktrace

为什么呢?可能是什么问题呢?我错过了什么?我该如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

你在Hibernate世界中,所以你需要使用Hibernate实体名称而不再使用SQL表名。默认情况下,实体名称是类的简单名称。

所以你应该写一些类似的东西:

select status from KM_ProjectInfoStatus status order by status.name

Google有关HQL / JPQL的更多信息,请参阅详细信息。

答案 1 :(得分:1)

HQL需要classname和SQL需要表名

在您的HQL中使用KM_ProjectInfoStatus而不是KM_PROJECT_INFO_STATUS

@NamedQueries({
        @NamedQuery(name = "kmProjectInfoStatusList", query = "select status from KM_ProjectInfoStatus status order by status.name") ,
        @NamedQuery(name = "kmProjectInfoStatusById", query = "SELECT status  FROM KM_ProjectInfoStatus status  where lower(status.idProjectInfoStatus) = :statusId")
})

HQL thus should not use table names, but entity class names

答案 2 :(得分:1)

这应该是HQL查询(而不是SQL):

SELECT status FROM KM_PROJECT_INFO_STATUS status where lower(status.idProjectInfoStatus) = :statusId

所以你不应该使用表名(KM_PROJECT_INFO_STATUS),而是使用实体类名(KM_ProjectInfoStatus),如下所示:

SELECT status FROM KM_ProjectInfoStatus status where lower(status.idProjectInfoStatus) = :statusId

这是与HQL FROM子句相关的link to Hibernate documentation

另请尝试遵循标准Java命名约定。它将使您的代码更具可读性:)