我正在使用JPA 2.1,Hibernate 4.3.6.Final和MySQL 5.5.37。如何编写进行连接的JPQL查询?我正在尝试下面
final String jpqlQuery = "SELECT m FROM Message m LEFT JOIN MessageReadDate mr " +
" INNER JOIN m.group g " +
" LEFT JOIN g.classroom c " +
" LEFT JOIN c.ROSTER u WHERE " +
" u.USER = :recipient AND " +
" u.ENABLED = 1 AND " +
" c.ENABLED = 1 AND " +
" g.NAME = '' AND " +
" m.author <> :author";
Query query = m_entityManager.createQuery(jpqlQuery);
但得到错误“加入的路径! ...路径无效:&#39; g.classroom&#39;“。
org.hibernate.hql.internal.ast.ErrorCounter - Path expected for join!
Path expected for join!
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:379)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3903)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3689)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:126)
at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:88)
at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at com.sun.proxy.$Proxy68.createQuery(Unknown Source)
at org.mainco.subco.messaging.repo.MessageDaoImpl.getUnreadClassAnnouncements(MessageDaoImpl.java:161)
at org.mainco.subco.messaging.repo.MessageDaoImpl.getUnreadMessages(MessageDaoImpl.java:140)
at org.mainco.subco.messaging.repo.MessageDaoIT.testGetUnreadMessages(MessageDaoIT.java:125)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java: 74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
[ERROR]: org.hibernate.hql.internal.ast.ErrorCounter - Invalid path: 'g.classroom'
[ERROR]: org.hibernate.hql.internal.ast.ErrorCounter - Invalid path: 'g.classroom'
Invalid path: 'g.classroom'
at org.hibernate.hql.internal.ast.util.LiteralProcessor.lookupConstant(LiteralProcessor.java:129)
at org.hibernate.hql.internal.ast.tree.DotNode.resolve(DotNode.java:225)
at org.hibernate.hql.internal.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:126)
at org.hibernate.hql.internal.ast.HqlSqlWalker.createFromJoinElement(HqlSqlWalker.java:387)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.joinElement(HqlSqlBaseWalker.java:3903)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElement(HqlSqlBaseWalker.java:3689)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromElementList(HqlSqlBaseWalker.java:3567)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.fromClause(HqlSqlBaseWalker.java:708)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:564)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:301)
at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:249)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:278)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:206)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:158)
…
我的消息实体如下......
@Entity
@Table(name = "msg")
public class Message
{
@Id
@NotNull
@GeneratedValue(generator = "uuid-strategy")
@Column(name = "ID")
private String id;
@Column(name = "MESSAGE", columnDefinition="LONGTEXT")
private String message;
@ManyToOne
@JoinColumn(name = "GROUP_ID", nullable = false, updatable = true)
private Group group;
我的团体实体如下......
@Entity
@Table(name = "msg_group")
public class Group
{
@Id
@NotNull
@GeneratedValue(generator = "uuid-strategy")
@Column(name = "ID")
private String id;
@Column(name = "NAME")
private String name;
@ManyToOne
@JoinColumn(name = "CLASSROOM_ID", nullable = true, updatable = true)
private Classroom classroom;
那为什么我不能引用“课堂”属性呢?
谢谢, - 戴夫
答案 0 :(得分:3)
如果你想在HQL中使用JOIN,那么你只能在From
子句中提到的类的属性上使用它。
这意味着,在这个特定的行中:
SELECT m FROM Message m LEFT JOIN MessageReadDate mr
hibernate检查MessageReadDate
是否被定义为Message
类中的属性,该属性在此处被视为路径。由于没有任何名为MessageReadDate
的内容,因此会引发异常。
要解决此问题,请在MessageReadDate
课程中为Message
课程添加所需的媒体资源,让我们说mrd
(您可以将您的关系作为一对一或在 - to-many或etc)然后使用这样的查询:
SELECT m FROM Message m LEFT JOIN m.mrd
通过这种方式,我们告诉hibernate如何将消息与其相应的属性连接起来,因此连接的路径对于休眠是明确的。
答案 1 :(得分:2)
Hibernate报告的问题在第一行:
final String jpqlQuery = "SELECT m FROM Message m LEFT JOIN MessageReadDate mr "...
LEFT JOIN语句中的。在 hql 中,JOIN必须表达关系,例如
LEFT JOIN m.MessageReadDate mr // the m is referencing the MessageReadDate
如果没有参考,我们仍然可以使用它,但使用笛卡尔积
FROM Message m, MessageReadDate mr
在这种情况下,将发布CROSS JOIN
见:
小引用:
可以出现多个类,从而产生笛卡尔积或“#34; cross&#34;加入。
from Formula, Parameter
from Formula as form, Parameter as param
您还可以使用连接将别名分配给关联实体或值集合的元素。例如:
from Cat as cat
inner join cat.mate as mate