【问题标题】:What is wrong with this JPQL query?这个 JPQL 查询有什么问题?
【发布时间】:2017-03-07 19:04:04
【问题描述】:

我正在尝试在我的服务器上执行闲置查询 这是我的查询:

List<Object> result = entityManager
    .createQuery("SELECT post FROM PostMW post LEFT OUTER JOIN LikeMW likes ON post.id = likes.post_id AND likes.user_id =:userID")
    .setParameter("userID", 1)
    .setFirstResult(offset).setMaxResults(itemsPerPage)
    .getResultList();

Object PostMW(不完整,但有我想说的必要数据):

@Entity
@Table(name="POST")
public class PostMW{

    @Id
    @Column(name="id", nullable=false)
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="media_id", nullable=false, unique=true)
    private MediaMW media;

    @Column(name="latitude", nullable=false)
    private BigDecimal latitude;

    @Column(name="longitude", nullable=false)
    private BigDecimal longitude;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="challenge_id", nullable=false)
    private ChallengeMW challenge;

    // GETTERS AND SETTERS //
    ....
}

这里是 LikeMW(完整)所以你看,它只有两个表 USER 和 POST 的主键:

@Entity
@Table(name="LIKES")
public class LikeMW {

    @Id
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "post_id", nullable=false)
    @JsonBackReference
    private PostMW post;

    @Id
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="user_id", nullable=false)
    private UserMW user;

    // GETTERS AND SETTERS //
    ...
}

我收到 nullpointerException!我想不通为什么... 例外:

java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: 
Exception Description: Internal problem encountered while compiling [SELECT post FROM PostMW post LEFT OUTER JOIN LikeMW likes ON post.id = likes.post_id AND likes.user_id =:userID].
Internal Exception: java.lang.NullPointerException
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1605)
at com.jonathan.myworld.model.dao.impl.PostDaoImpl.list(PostDaoImpl.java:72)
at com.jonathan.myworld.service.impl.FeedServiceImpl.getFeed(FeedServiceImpl.java:45)
at com.jonathan.myworld.UserWS.login(UserWS.java:151)
at com.jonathan.myworld.UserWS.loginWithGoogle(UserWS.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.appengine.tools.development.agent.runtime.Runtime.invoke(Runtime.java:130)
at com.google.api.server.spi.SystemService.invokeServiceMethod(SystemService.java:363)
at com.google.api.server.spi.SystemServiceServlet.execute(SystemServiceServlet.java:113)
at com.google.api.server.spi.SystemServiceServlet.doPost(SystemServiceServlet.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:128)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:63)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:50)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectRequest(DevAppServerModulesFilter.java:366)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doDirectModuleRequest(DevAppServerModulesFilter.java:349)
at com.google.appengine.tools.development.DevAppServerModulesFilter.doFilter(DevAppServerModulesFilter.java:116)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:98)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:511)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: Exception [EclipseLink-0] (Eclipse Persistence Services - 2.5.1.v20130918-f2b9fc5): org.eclipse.persistence.exceptions.JPQLException
Exception Description: Internal problem encountered while compiling [SELECT post FROM PostMW post LEFT OUTER JOIN LikeMW likes ON post.id = likes.post_id AND likes.user_id =:userID].
Internal Exception: java.lang.NullPointerException
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildUnexpectedException(HermesParser.java:207)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:296)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.buildQuery(HermesParser.java:163)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:142)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.buildEJBQLDatabaseQuery(EJBQueryImpl.java:116)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:102)
at org.eclipse.persistence.internal.jpa.EJBQueryImpl.<init>(EJBQueryImpl.java:86)
at org.eclipse.persistence.internal.jpa.EntityManagerImpl.createQuery(EntityManagerImpl.java:1603)
... 49 more
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.queries.DatabaseQuery.addArgument(DatabaseQuery.java:449)
at org.eclipse.persistence.queries.DatabaseQuery.addArgument(DatabaseQuery.java:419)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.addArguments(HermesParser.java:98)
at org.eclipse.persistence.internal.jpa.jpql.HermesParser.populateQueryImp(HermesParser.java:287)

我找不到我做错了什么。任何建议将不胜感激!

编辑:

现在尝试这个查询:

List<Object> result = entityManager
                .createQuery("SELECT post FROM PostMW post LEFT OUTER JOIN post.hasLiked liked ON post.id = liked.post_id AND liked.user_id =:userID")
                .setParameter("userID", 1)
                .setFirstResult(offset).setMaxResults(itemsPerPage)
                .getResultList();

更新了我的对象。现在我的 PostMW 对象有

@Entity
@Table(name="POST")
public class PostMW{
    ...
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="LIKES", joinColumns=@JoinColumn(name="post_id"), inverseJoinColumns=@JoinColumn(name="user_id"))
    private List<UserMW> hasLiked;
    ...
}

UserMW

@Entity
@Table(name="USER")
public class UserMW {
    ...
    @Id
    @Column(name="id", nullable=false)
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name="name", nullable=false, length=255)
    private String name;
    ...
}

得到相同的异常 T.T

【问题讨论】:

标签: java mysql jpa eclipselink jpql


【解决方案1】:

JPQL 使用类/字段而不是表/列。 JPQL != SQL

【讨论】:

    【解决方案2】:

    完全相同的错误被报告为错误:

    https://bugs.eclipse.org/bugs/show_bug.cgi?id=394033

    然后又是 glassfish 虫子: https://java.net/jira/si/jira.issueviews:issue-html/GLASSFISH-20456/GLASSFISH-20456.html

    您能否验证您是否使用带有修复程序的 EclipseLink 版本?

    【讨论】:

    • 我正在使用 EclipseLink 2.5.2。没事吧?
    • 正如其中一个错误 cmets 建议的那样,您可以尝试添加
    • 到您的持久性属性
    • 我还注意到您没有将 user_id 定义为 UserMW 中的列名。因此,尽管您在 LikeMW 中有 @JoinColumn(name="user_id", nullable=false ,但在 UserMW 中没有带有 user_id 的列。我认为在 UserMW 中定义 user_id 列名称将解决您的问题。
    【解决方案3】:

    是否对用于调用 createQuery 的对象 entityManager 进行了空检查?可能是该对象为 null,并且在该行抛出了 java.lang.NullPointerException。

    【讨论】:

      【解决方案4】:

      您的 JPQL 格式错误。 JPQL 中没有JOIN...ON

      由于您没有从 PostLike 的引用,因此您可以将查询反转为类似于

      的内容
      SELECT likes.post FROM LikeMW likes WHERE likes.user.id = :userID
      

      这将获得具有给定用户 ID 的用户喜欢的帖子。

      如果您打算使用偏移量/限制,您还需要在查询中添加 order by。

      【讨论】:

      • 但在这种情况下,我将只有给定用户喜欢的帖子。我的意图是获取所有帖子,但对于每个帖子,我想知道给定用户是否喜欢该帖子。请在此处查看我的问题:stackoverflow.com/questions/40218027/… 感谢您对 order by 的建议:)
      猜你喜欢
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 2011-09-29
      • 2011-10-13
      • 2010-09-07
      相关资源
      最近更新 更多