【问题标题】:What is different of ways when using join jpa in spring data jpa在spring data jpa中使用join jpa有什么不同
【发布时间】:2017-09-29 00:05:38
【问题描述】:

我对 spring data jpa 有疑问。我不知道为什么?有什么道理?

问题: 我有 2 张桌子: 1. 接入点数据库

@Entity
@Table(name = "access_point")
public class AccessPointDb  implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "access_point_id", unique = true, nullable = false)
private Long accessPointId;

@Column(name = "ap_mac")
private String apMac;

@Column(name = "zone_id")
private Long zoneId;

@Column(name = "description")
private String description;

@Column(name = "created_date")
@Temporal(TemporalType.TIMESTAMP)
private Date createdDate;

@Column(name = "created_by")
private Long createdBy;

@Column(name = "updated_date")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedDate;

@Column(name = "updated_by")
private Long updatedBy; 


public AccessPointDb() {
    super();
}

public Long getAccessPointId() {
    return accessPointId;
}

public void setAccessPointId(Long accessPointId) {
    this.accessPointId = accessPointId;
}

public String getApMac() {
    return apMac;
}

public void setApMac(String apMac) {
    this.apMac = apMac;
}

public Long getZoneId() {
    return zoneId;
}

public void setZoneId(Long zoneId) {
    this.zoneId = zoneId;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}



public Date getCreatedDate() {
    return createdDate;
}

public void setCreatedDate(Date createdDate) {
    this.createdDate = createdDate;
}

public Long getCreatedBy() {
    return createdBy;
}

public void setCreatedBy(Long createdBy) {
    this.createdBy = createdBy;
}

public Date getUpdatedDate() {
    return updatedDate;
}

public void setUpdatedDate(Date updatedDate) {
    this.updatedDate = updatedDate;
}

public Long getUpdatedBy() {
    return updatedBy;
}

public void setUpdatedBy(Long updatedBy) {
    this.updatedBy = updatedBy;
}

}


2. 区域数据库

@Entity
@Table(name = "zone")

public class ZoneDb extends BaseEntity implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "zone_id", unique = true, nullable = false)
private Long zoneId;

@Column(name = "zone_name")
private String zoneName;

@Column(name = "description")
private String description;

public ZoneDb() {
    super();
}

public Long getZoneId() {
    return zoneId;
}

public void setZoneId(Long zoneId) {
    this.zoneId = zoneId;
}

public String getZoneName() {
    return zoneName;
}

public void setZoneName(String zoneName) {
    this.zoneName = zoneName;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

 }

在我的代码中。我想加入上面的 2 个表格: 我使用代码:"SELECT a.accessPointId, z.zoneName FROM AccessPointDb AS a LEFT JOIN ZoneDb AS z ON z.zoneId = z.zoneId"; 并创建查询:query = em.createQuery(stmt, persistentClass);

但我收到错误:

antlr.SemanticException: Path expected for join!

org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [SELECT a  FROM com.sbd.cms.data.entities.AccessPointDb AS a LEFT JOIN ZoneDb AS z ON z.zoneId = z.zoneId  WHERE 1=1 ]; nested exception is java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [SELECT a  FROM com.sbd.cms.data.entities.AccessPointDb AS a LEFT JOIN ZoneDb AS z ON z.zoneId = z.zoneId  WHERE 1=1 ]
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:384)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:246)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:491)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:59)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:213)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:147)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at com.sbd.cms.data.repository.implement.AccessPointRepository$$EnhancerBySpringCGLIB$$a5b2c11f.search(<generated>)
    at com.sbd.cms.biz.accessPoint.AccessPointBusinessImplement.search(AccessPointBusinessImplement.java:42)
    at com.sbd.cms.web.api.controller.AccessPointController.search(AccessPointController.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:115)
    at org.springframework.boot.web.support.ErrorPageFilter.access$000(ErrorPageFilter.java:59)
    at org.springframework.boot.web.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:90)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.boot.web.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:108)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:474)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:783)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:798)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1434)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [SELECT a  FROM com.sbd.cms.data.entities.AccessPointDb AS a LEFT JOIN ZoneDb AS z ON z.zoneId = z.zoneId  WHERE 1=1 ]
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1679)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:313)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:347)
    at com.sun.proxy.$Proxy93.createQuery(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298)
    at com.sun.proxy.$Proxy93.createQuery(Unknown Source)
    at com.sbd.cms.data.repository.implement.GenericRepositoryImplement.findByQuery(GenericRepositoryImplement.java:189)
    at com.sbd.cms.data.repository.implement.GenericRepositoryImplement.pagingCustom(GenericRepositoryImplement.java:64)
    at com.sbd.cms.data.repository.implement.AccessPointRepository.search(AccessPointRepository.java:56)
    at com.sbd.cms.data.repository.implement.AccessPointRepository$$FastClassBySpringCGLIB$$9bda46e0.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.dao.support

但我不知道为什么?

然后当我在表 accessPointDb 中添加多对一时。

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "zoneId")
private ZoneDb zoneDb;

我使用查询

 SELECt a.accessPointId, z.zoneName FROM AccessPointDb AS a LEFT JOIN a.zoneDb AS z ON z.zoneId = z.zoneId

 SELECt a.accessPointId, z.zoneDb.zoneName FROM AccessPointDb AS a

没关系。

但我想知道上述方法有什么区别?

【问题讨论】:

  • JPQL JOIN 是跨关系的。您的第一个不是跨关系,而是在两个单独的实体之间。请参阅 JPA 规范和您的 JPA 提供者的文档
  • @NeilStockton 感谢您的建议。

标签: java hibernate jpa spring-boot spring-data


【解决方案1】:
SELECT a.accessPointId, z.zoneName FROM AccessPointDb AS a LEFT JOIN ZoneDb AS z ON z.zoneId = z.zoneId"

这个(上面的查询)是一个本机查询,这就是它给出错误的原因,因为您将它与 EntityManager 的 createQuery 方法一起使用

em.createQuery(stmt, persistentClass);

您应该使用createNativeQuery 而不是createQuery 来运行本机查询。

原生查询:原生查询指的是实际的sql查询(指的是实际的数据库对象)。这些查询是可以使用数据库客户端直接在数据库中执行的sql语句。

查询 :查询是指JPQL/HQL 查询,其语法类似于通常用于执行DML 语句(CRUD 操作)的SQL。 在 JPA 中,您可以使用 entityManager.createQuery() 创建查询。

【讨论】:

  • 上面的查询不是navtiveQuery,因为AccessPointDb和ZoneDb是两个实体不是表。
  • @ngotiensy,哦,对不起,我错过了@Table 注释,实际上 SELECT a.accessPointId, z.zoneName FROM AccessPointDb AS a LEFT JOIN ZoneDb AS z ON z.zoneId = z.zoneId"; and create query : query = em.createQuery(stmt, persistentClass); 在这个时候你的实体 AccessPointDb 没有与 ZoneDb 关联,并且 hql/JPQL 在实体上工作,它关联实体或元素使用连接的值集合,因为当时 ZoneDb 没有与您的 AccessPointDb 实体关联,所以休眠抛出异常:org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join!
  • 感谢您的回复。但我认为这里的不同之处在于 Spring Data jpa 在休眠状态下运行,它不是 jpa 的标准。我将更改为使用 elipse 链接运行它。也许没关系。
  • @ngotiensy 最新的 JPA 规范 (2.1) 未涵盖在不相关实体上的连接,但是 Hibernate 5.1.0+ 和 EclipseLink 2.4.0+ 支持临时连接。 blog.anthavio.net/2016/03/join-unrelated-entities-in-jpa.html 所以这里是 hibernate 的一个有效例外,因为 JPA 不支持 unlinked join。
猜你喜欢
  • 2016-07-29
  • 2018-03-20
  • 2021-12-19
  • 2016-08-28
  • 1970-01-01
  • 1970-01-01
  • 2017-08-21
  • 1970-01-01
  • 2021-12-22
相关资源
最近更新 更多