休眠中的CRUD给表没有映射异常

时间:2017-04-06 06:46:44

标签: java hibernate hql

我正在尝试在hibernate中实现CRUD操作。但是我得到“Table not mapped”错误。而且,在我的代码中,Query已经被弃用了。 据我所知,表的映射只是这样完成的。那么,这里有什么问题?

代码

public void deleteTeacher(String name) {
    Transaction tx = null;
    Session session = Utility.getSessionFactory().openSession();
    tx = session.beginTransaction();
    Query query = session.createQuery("from vi where name=" + name);
    //Teacher teacher=(Teacher)session.get(Teacher.class, name);
    Teacher teacher = (Teacher) query.getSingleResult();
    session.delete(teacher);
    session.getTransaction().commit();
    session.close();
}

错误

Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: vi is not mapped [from vi where name=Aayushi]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:131)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:658)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:102)
    at DAO.deleteTeacher(DAO.java:45)
    at MainClass.main(MainClass.java:37)
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: vi is not mapped [from vi where name=Aayushi]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.generateQueryException(QuerySyntaxException.java:79)
    at org.hibernate.QueryException.wrapWithQueryString(QueryException.java:103)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:217)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:141)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:77)
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:153)
    at org.hibernate.internal.AbstractSharedSessionContract.getQueryPlan(AbstractSharedSessionContract.java:541)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:650)
    ... 3 more
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: vi is not mapped
    at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171)
    at org.hibernate.hql.internal.ast.tree.FromElementFactory.addFromElement(FromElementFactory.java:91)
    at org.hibernate.hql.internal.ast.tree.FromClause.addFromElement(FromClause.java:79)
    at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromElement(HqlSqlWalker.java:324)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3696)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3585)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:720)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:576)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:313)
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:261)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:266)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:189)
    ... 9 more

配置类是

teacher.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<hibernate-mapping>
    <class name="Teacher" table="vi">

        <composite-id>
            <key-property name="name" column="name"  />
            <key-property name="subject" column="subject" length="10" />
        </composite-id>


    </class>
</hibernate-mapping> 

3 个答案:

答案 0 :(得分:1)

字符串应位于''之间,因此您的查询应如下所示:

Query query=session.createQuery("from vi where name='" + name + "');

但是为了避免任何语法错误或SQL注入,您必须使用:

Query query = session.createQuery("from vi where name=:name");
query.setParameter("name", name);

修改

为什么你根本不使用:

//no need to select your object before you delete it
//Query query = session.createQuery("from vi where name=" + name);
//Teacher teacher=(Teacher)session.get(Teacher.class, name);
//Teacher teacher = (Teacher) query.getSingleResult();

//just make a delete query directly
String hql = "DELETE FROM vi WHERE name= :name";
Query query = session.createQuery(hql);
query.setParameter("name", name);
int result = query.executeUpdate();

在删除之前避免选择,如果结果为null,则可能导致此错误。

答案 1 :(得分:0)

在HQL中,您必须使用类名,而不是表名,因此oyur查询必须是:

"from Teacher where name="+Name

此外,您应该使用参数绑定来防止SQL注入

答案 2 :(得分:0)

鉴于你的模型,你在这里做了一些不好的假设。您的Teacher模型使用namesubject的复合键,但您的代码假定按名称定位Teacher会净化单行结果,而且只是'总是如此。

您需要调整数据模型并强制name在所有Teacher实体中都是唯一的,这在实际情况下再次无意义或修改您的删除代码说明这一点。

以下代码假设Hibernate 5.2,因此它可能需要一些小的调整,但前提仍然完全相同,无论如何:

final List<Teacher> teachers = session
   .createQuery( "FROM Teacher t WHERE t.name = :name", Teacher.class )
   .setParameter( "name", teacherName )
   .getResultList();

for ( Teacher teacher : teachers ) {
  session.remove( teacher );
}

要@ YCF_L关于在删除之前选择的观点,如果您的代码说明了查询的结果可以,那么这实际上是不是一个问题em>是空的。但是因为按照上面的实际场景,多个教师可以具有相同的名称,它不会给你一个错误,因为返回的List<>将为空,删除-loop被跳过或包含值并执行delete for-loop。

正如所指出的那样,如果您愿意,可以盲目地执行删除操作而不会获取数据,而且它看起来非常相似。

int deleteCount = session
  .createQuery( "DELETE FROM Teacher t WHERE t.name = :name" )
  .setParameter( "name", teacherName )
  .executeUpdate();

在这种情况下,您可以使用返回值deleteCount来记录已删除的教师数量或执行某些特定代码(如果该值可能您所期望的。

最后,虽然其他人已指出使用参数绑定来避免SQL注入的好处,但参数绑定对于许多其他原因也很重要。

例如,绑定参数SQL可以由数据库进行优化,规划和缓存,并重用于将来的查询。当您将实际值直接引入SQL时,大多数数据库平台都会按原样缓存查询,因此,如果使用相同的参数提供与以前完全相同的SQL,则只能获得此优势。