我正在尝试使用Hibernate HQL创建连接语句。我从一个未映射为类的联结表中获取数据。基本上我有类User和class Chapter,带有user_chapters联结表。我想用给定的id来获取User的所有主题。这是代码:
使用的DAO方法:
@SuppressWarnings("unchecked")
public List<Chapter> getChaptersOfUser(int id){
List<Chapter> q = new ArrayList<Chapter>();
Transaction tx=null;
try{
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
tx = session.beginTransaction();
Query query = session.createQuery("FROM Chapter INNER JOIN user_chapters ON chapter.id = user_chapters.chapter_id WHERE user_chapters.user_id = :id");
query.setParameter("id", id);
q = query.list();
tx.commit();
}catch (HibernateException e) {
if (tx != null) {
tx.rollback();
}
LOGGER.error("", e);
}
return q;
}
这是错误日志:
Exception in thread "main" java.lang.IllegalArgumentException: org.hibernate.QueryException: Unable to resolve path [user_chapters.user_id], unexpected token [user_chapters] [FROM models.Chapter INNER JOIN user_chapters ON chapter.id = user_chapters.chapter_id WHERE user_chapters.user_id = :id]
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:663)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:102)
at dao.ChapterDAO.getChaptersOfUser(ChapterDAO.java:100)
at Main.main(Main.java:25)
Caused by: org.hibernate.QueryException: Unable to resolve path [user_chapters.user_id], unexpected token [user_chapters] [FROM models.Chapter INNER JOIN user_chapters ON chapter.id = user_chapters.chapter_id WHERE user_chapters.user_id = :id]
at org.hibernate.QueryException.generateQueryException(QueryException.java:120)
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:546)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:655)
... 3 more
Caused by: org.hibernate.QueryException: Unable to resolve path [user_chapters.user_id], unexpected token [user_chapters]
at org.hibernate.hql.internal.ast.tree.IdentNode.resolveAsNakedComponentPropertyRefLHS(IdentNode.java:299)
at org.hibernate.hql.internal.ast.tree.IdentNode.resolve(IdentNode.java:143)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:114)
at org.hibernate.hql.internal.ast.tree.DotNode.resolveFirstChild(DotNode.java:167)
at org.hibernate.hql.internal.ast.HqlSqlWalker.lookupProperty(HqlSqlWalker.java:694)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.addrExpr(HqlSqlBaseWalker.java:5003)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1286)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4707)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:4175)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:2138)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:815)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:609)
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
章实体类就是这个:
@Entity
@Table(name = "chapter")
public class Chapter {
@Id
int id;
String title;
int year;
public Chapter(int id,String title,int year){
this.id=id;
this.title=title;
this.year=year;
}
public Chapter(){}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public int getYear() {
return year;
}
public void setId(int id) {
this.id = id;
}
public void setTitle(String title) {
this.title = title;
}
public void setYear(int year) {
this.year = year;
}
}
hql查询的错误点。那么,你认为我应该映射联结类吗?或者你在这里看到任何其他解决方案?
答案 0 :(得分:0)
像这样的东西(在章节的用户实体中也是如此):
@Entity
public class Chapter {
private Set<User> users;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinTable(name = "user_chapters", joinColumns = {
@JoinColumn(name = "user_id", nullable = false, updatable = true) },
inverseJoinColumns = { @JoinColumn(name = "chapter_id", nullable = false, updatable = true)
})
public Set<User> getUsers() {
return users;
}
}
我实际上并不确定HQL。我在自己的项目中找到了一个旧的例子,我在其中使用了SQL而不是:
String sql = "select ch from Chapter ch join ch.users us where us.id = :id
也许这会奏效:)