【问题标题】:Using place holders in Hibernate Native SQL query在 Hibernate Native SQL 查询中使用占位符
【发布时间】:2023-03-17 03:40:01
【问题描述】:

我有一个实体 Book,它与 Publisher 保持多对一关系。这是 Book 的休眠映射文件

<hibernate-mapping package="com.pramati.model">
    <class name="Book" table="BOOK">
        <id name="id" column="ID" type="long">
            <generator class="native"/>
        </id>
        <property name="name" column="NAME" type="string"/>
        <property name="isbn" type="int">
            <column name="ISBN" unique="true" not-null="true"/>
        </property>
        <property name="price" column="PRICE" type="double"/>
        <property name="bookIndex" column="BOOK_INDEX" type="int"/>
        <many-to-one name="publisher" class="Publisher" column="PUBLISHER_ID" cascade="save-update,delete"/>
    </class>
</hibernate-mapping>

这是我正在使用的本机查询:

String sql = "SELECT {b.*}  FROM BOOK book LEFT OUTER JOIN PUBLISHER pub ON book.PUBLISHER_ID = pub.ID  WHERE book.price > 100 ";
Query query = session.createSQLQuery(sql).addEntity("b", Book.class);
List list = query.list();

执行此操作时,我收到以下异常:

20:39:49,438 DEBUG SQL:401 - SELECT b.ID as ID0_0_, b.NAME as NAME0_0_, b.ISBN as ISBN0_0_, b.PRICE as PRICE0_0_, b.BOOK_INDEX as BOOK5_0_0_, b.PUBLISHER_ID as PUBLISHER6_0_0_ FROM BOOK book LEFT OUTER JOIN PUBLISHER pub ON book.PUBLISHER_ID = pub.ID WHERE book.price > 100 
20:39:49,466  WARN JDBCExceptionReporter:77 - SQL Error: 1054, SQLState: 42S22
20:39:49,467 ERROR JDBCExceptionReporter:78 - Unknown column 'b.ID' in 'field list'
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
    at org.hibernate.loader.Loader.doList(Loader.java:2223)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
    at org.hibernate.loader.Loader.list(Loader.java:2099)
    at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)
    at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)
    at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
    at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:152)
    at com.pramati.model.Publisher.main(Publisher.java:95)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'b.ID' in 'field list'
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

为什么会这样?如果我只是在 addEntity 中将别名替换为 'book' 并尝试使用 'select {book.*} ..' 获取它(即在 SQL 和 addEntity 方法中使用相同的别名),它工作正常。

【问题讨论】:

    标签: hibernate


    【解决方案1】:

    您应该使用{book.*}。否则 SQL 驱动程序不知道它在查询中指的是什么。

    如果您查看引起的原因,您会发现是 mysql 驱动程序引发了异常。 Hibernate 正在用b.ID, ... 适当地替换{b.*},但驱动程序不知道字段映射到FROM 子句中的什么。

    【讨论】:

    • 我们是否必须为 SQL 和 Hibernate 中的表使用相同的别名?
    • 这是我阅读的表单文档:sess.createSQLQuery("SELECT c.*,m.* FROM CATS c,CATS m WHERE c.MOTHER_ID = c.ID").addEntity(" cat",Cat.class).addEntity("mother",Cat.class) 由于名称冲突,查询会失败。此外,在某些数据库上,返回的列别名很可能是“c.ID”、“c.NAME”等,它们不等于映射中指定的列(“ID”和“NAME”)。以下解决它: sess.createSQLQuery("SELECT {cat.*},{mother.*} FROM CATS c,CATS m WHERE c.MOTHER_ID = c.ID").addEntity("cat",Cat.class).addEntity (“妈妈”,Cat.class)
    • @PrasanthNath:您对文档所说的内容是正确的。但是当我尝试遵循它时,我会得到与您相同的结果。当我使用 {book.*} 它的行为。查看该部分中的其他示例,它们不一致,有时在同一个示例查询中。我认为这里的问题在于文档。
    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 2020-06-09
    • 2021-11-25
    • 2020-06-16
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多