2017-04-06 59 views
0

我想在hibernate中實現CRUD操作。但是我得到「表未映射」錯誤。此外,查詢即將在我的代碼中被棄用。 據我所知,表的映射只能以這種方式完成。那麼,這裏的問題是什麼?CRUD在休眠給表沒有映射異常

代碼

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> 

回答

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(); 

避免在刪除之前進行選擇,如果結果爲空,則會導致此錯誤。

+0

即使我得到約束違規異常。鏈接到我的github代碼是https://github.com/aayushis12/Hibernate請幫助 – Aayushi

+0

檢查我的編輯@aayushi –

0

在HQL你有類名,不與表名的工作,所以oyur查詢必須是:

"from Teacher where name="+Name 

而且你應該使用參數綁定,防止SQL注入

+0

如果我做的類名,然後我得到ConstraintViolationException @Jens – Aayushi

+0

'ConstraintViolationException'意味着你有一個外鍵,這是不知道 – Jens

+1

@YCF_L謝謝 – Jens

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的角度選擇刪除之前,其實這是如果您的代碼導致查詢的結果可能爲空,則會出現問題。但是因爲按照上面的多個教師可能具有相同的名稱,它不會給你一個錯誤,因爲返回的List<>將爲空,在該位置刪除for循環被跳過或包含值並執行刪除for循環。

正如指出的那樣,如果您願意,它會看起來非常相似,您可以在不提取數據的情況下盲目執行刪除操作。

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

在這種情況下,你可以使用返回值deleteCount登錄多少教師被刪除或如果該值可能你所期望的執行一些特定的代碼。

最後,雖然其他人指出使用參數綁定避免SQL注入的好處,但參數綁定對於其他許多原因也很重要。

例如,綁定參數SQL可以被數據庫優化,計劃和緩存,並可用於未來的查詢。將實際值直接引入SQL中時,大多數數據庫平臺都會按原樣緩存查詢,因此如果您提供的SQL與以前的參數完全相同,則只能獲得此優勢。