Hibernate HQL - 不存在抛出 org.hibernate.exception.SQLGrammarException 的条件:
Posted
技术标签:
【中文标题】Hibernate HQL - 不存在抛出 org.hibernate.exception.SQLGrammarException 的条件:【英文标题】:Hibernate HQL - not exists condition throwing org.hibernate.exception.SQLGrammarException: 【发布时间】:2017-03-17 15:50:58 【问题描述】:我有 3 个表(多对多条件)- Stock、Categories 和一个中间 Stock_Category。
在 Hibernate 中,我有 2 个实体 - 具有一组类别的股票和具有一组股票的类别实体。
现在我想获取不属于特定类别的所有股票,由类别名称标识。
我有以下用 HQL 编码的相关子查询:
Query query = session.createQuery("Select s from Stock s join fetch s.categories c " +
"where not exists (Select cs from Category cs " +
"where s in cs.stocks and cs.categoryname = :categoryname)");
query.setParameter("categoryname", "MATTEL");
似乎 hibernate 可以理解查询,因为它在控制台中提供了自己的解释版本,但仍然抛出 Sql 异常。缺失的因素是什么?
由休眠提供:
Hibernate:
/* Select
s
from
Stock s
join
fetch s.categories c
where
not exists (
Select
cs
from
Category cs
where
s in cs.stocks
and cs.categoryname = :categoryname
) */ select
stock0_.STOCK_ID as STOCK_ID1_1_0_,
categories1_.CATEGORY_ID as CATEGORY_ID1_0_1_,
stock0_.STOCK_CODE as STOCK_CODE2_1_0_,
stock0_.STOCK_NAME as STOCK_NAME3_1_0_,
categories1_.CATEGORY_NAME as CATEGORY_NAME2_0_1_,
categories1_.CATEGORY_DESC as CATEGORY_DESC3_0_1_,
categories1_.STOCK_ID as STOCK_ID4_1_0__,
categories1_.CATEGORY_ID as CATEGORY_ID1_0_0__
from
STOCK stock0_
inner join
CATEGORY categories1_
on stock0_.STOCK_ID=categories1_.STOCK_ID
where
not (exists (select
category2_.CATEGORY_ID
from
CATEGORY category2_,
STOCK stocks3_
where
category2_.CATEGORY_ID=stocks3_.CATEGORY_ID
and (stock0_.STOCK_ID in (.))
and category2_.CATEGORY_NAME=?))
这是 CATEGORY 表的实体类:
@Entity
@Table(name = "category")
public class Category implements java.io.Serializable
private Integer categoryId;
private String categoryname;
private String categorydesc;
private Set<Stock> stocks = new HashSet<Stock>(0);
public Category()
public Category(String name, String desc)
this.categoryname = name;
this.categorydesc = desc;
public Category(String name, String desc, Set<Stock> stocks)
this.categoryname = name;
this.categorydesc = desc;
this.stocks = stocks;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "CATEGORY_ID", unique = true, nullable = false)
public Integer getCategoryId()
return this.categoryId;
public void setCategoryId(Integer categoryId)
this.categoryId = categoryId;
@Column(name = "CATEGORY_NAME", nullable = false, length = 10)
public String getCategoryname()
return this.categoryname;
public void setCategoryname(String name)
this.categoryname = name;
@Column(name = "[CATEGORY_DESC]", nullable = false)
public String getCategorydesc()
return this.categorydesc;
public void setCategorydesc(String desc)
this.categorydesc = desc;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "categories")
public Set<Stock> getStocks()
return this.stocks;
public void setStocks(Set<Stock> stocks)
this.stocks = stocks;
这是 Category.hbm.xml 中的映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Mar 17, 2017 8:59:40 AM by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.mkyong.stock.Category" table="CATEGORY">
<id name="categoryId" type="java.lang.Integer">
<column name="CATEGORY_ID" />
<generator class="assigned" />
</id>
<property name="categoryname" type="java.lang.String">
<column name="CATEGORY_NAME" />
</property>
<property name="categorydesc" type="java.lang.String">
<column name="CATEGORY_DESC" />
</property>
<set name="stocks" table="STOCK" inverse="false" lazy="true">
<key>
<column name="CATEGORY_ID" />
</key>
<one-to-many class="com.mkyong.stock.Stock" />
</set>
</class>
</hibernate-mapping>
这是 STOCK 表的实体类:
@Entity
@Table(name = "stock", uniqueConstraints =
@UniqueConstraint(columnNames = "STOCK_NAME"),
@UniqueConstraint(columnNames = "STOCK_CODE") )
public class Stock implements java.io.Serializable
private Integer stockId;
private String stockCode;
private String stockName;
private Set<Category> categories = new HashSet<Category>(0);
public Stock()
public Stock(int stockid, String stockCode, String stockName)
this.stockId = stockid;
this.stockCode = stockCode;
this.stockName = stockName;
public Stock(String stockCode, String stockName, Set<Category> categories)
this.stockCode = stockCode;
this.stockName = stockName;
this.categories = categories;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "STOCK_ID", unique = true, nullable = false)
public Integer getStockId()
return this.stockId;
public void setStockId(Integer stockId)
this.stockId = stockId;
@Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
public String getStockCode()
return this.stockCode;
public void setStockCode(String stockCode)
this.stockCode = stockCode;
@Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
public String getStockName()
return this.stockName;
public void setStockName(String stockName)
this.stockName = stockName;
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "stock_category", joinColumns =
@JoinColumn(name = "STOCK_ID", nullable = false, updatable = false) ,
inverseJoinColumns = @JoinColumn(name = "CATEGORY_ID",
nullable = false, updatable = false) )
public Set<Category> getCategories()
return this.categories;
public void setCategories(Set<Category> categories)
this.categories = categories;
这是 Stock.hbm.xml 中的映射
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Mar 17, 2017 8:59:40 AM by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.mkyong.stock.Stock" table="STOCK">
<id name="stockId" type="java.lang.Integer">
<column name="STOCK_ID" />
<generator class="assigned" />
</id>
<property name="stockCode" type="java.lang.String">
<column name="STOCK_CODE" />
</property>
<property name="stockName" type="java.lang.String">
<column name="STOCK_NAME" />
</property>
<set name="categories" table="CATEGORY" inverse="false" lazy="true">
<key>
<column name="STOCK_ID" />
</key>
<one-to-many class="com.mkyong.stock.Category" />
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="">
<property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="hibernate.connection.username">system</property>
<property name="hibernate.connection.password">anishakshi1</property>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="use_sql_comments">true</property>
<mapping resource="com/mkyong/stock/Category.hbm.xml"/>
<mapping resource="com/mkyong/stock/Stock.hbm.xml"/>
</session-factory>
</hibernate-configuration>
【问题讨论】:
【参考方案1】:这样的属性更新
property name="hibernate.hbm2ddl.auto">验证
【讨论】:
【参考方案2】:我认为您可以加入而不是 in
声明:
"Select s from Stock s join fetch s.categories c " +
"where not exists (Select cs from Category cs inner join cs.stocks ss " +
"where s.id = ss.id and cs.categoryname = :categoryname)"
更新
您的 xml 映射是错误的。它们没有指定多对多映射。 您的注释似乎很好:
1) 移除这些属性:
<mapping resource="com/mkyong/stock/Category.hbm.xml"/>
<mapping resource="com/mkyong/stock/Stock.hbm.xml"/>
2) 将此属性添加到您的 sessionFactory 配置中:
<property name="packagesToScan" value="com.mkyong"/>
【讨论】:
我在尝试 OP 中给出的 HQL 之前尝试过。 Hibernate 给我这个内部连接错误: ERROR: ORA-00904: "CATEGORIES1_"."STOCK_ID": invalid identifier 尝试添加这两个表的实体映射 添加了实体类及其映射。 不确定为什么要使用注释和 hbm 文件.. 尝试仅使用注释并暂时省略 hbm 文件 我是 Hibernate 的新手,这是迄今为止我的导师教给我的唯一方法......以上是关于Hibernate HQL - 不存在抛出 org.hibernate.exception.SQLGrammarException 的条件:的主要内容,如果未能解决你的问题,请参考以下文章
org.hibernate.hql.QueryExecutionRequestException:org.hibernate.hql.QueryExecutionRequestException:
org.hibernate.hql.ast.QuerySyntaxException
原因:org.hibernate.QueryException:节点没有数据类型:org.hibernate.hql.internal.ast.tree.MethodNode
hibernate hsql得到错误节点没有数据类型:org.hibernate.hql.ast.tree.IdentNode