我正在尝试在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>
答案 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
模型使用name
和subject
的复合键,但您的代码假定按名称定位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,则只能获得此优势。