【问题标题】:Spring Boot JPA: Path expected for joinSpring Boot JPA:预期加入的路径
【发布时间】:2018-06-21 05:30:06
【问题描述】:

请注意:不是this one的骗子...我遇到了同样的例外,但原因不同!


JPA/Hibernate 在这里,被一个用 Groovy 编写的 Spring Boot 应用程序使用(Groovy 无关紧要;只是为了更好的衡量而提及它)。我有以下 3 个实体:

@Entity(name = 'accounts')
class Account {
    @Id
    @Column(name='account_id')
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id

    @Column(name='account_ref_id')
    String refId

    @Column(name = 'account_email')
    @NotEmpty
    String email

    @Column(name = 'account_username')
    String username
}

@Entity(name = 'security_token_types')
class SecurityTokenType {
  @Id
  @Column(name='security_token_type_id')
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  Long id

  @Column(name='security_token_type_ref_id')
  String refId

  @Column(name='security_token_type_name')
  String name

  @Column(name='security_token_type_label')
  String label

  @Column(name='security_token_type_description')
  String description
}

@Entity(name = 'security_tokens')
class SecurityToken {
    @Id
    @Column(name='security_token_id')
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id

    @Column(name='security_token_ref_id')
    String refId

    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = 'account_id', referencedColumnName = 'account_id')
    Account account

    @Column(name = 'security_token')
    String token

    @OneToOne(fetch = FetchType.EAGER, cascade = [CascadeType.PERSIST, CascadeType.MERGE])
    @JoinColumn(name = 'security_token_type_id', referencedColumnName = 'security_token_type_id')
    SecurityTokenType type

    @Column(name = 'security_token_generated_on')
    Date generatedOn
}

还有一个SecurityPersistor (DAO) 存储库:

interface SecurityTokenPersistor extends CrudRepository<SecurityToken, Long> {
    @Query("FROM security_tokens st INNER JOIN security_token_types stt ON st.security_token_type_id = stt.security_token_type_id WHERE stt.security_token_type_label = :type AND st.account_id = :accountId")
    Set<SecurityToken> findTokensByAccountAndType(@Param('accountId') Long accountId, @Param('type') String type)
}

在运行时我得到这些:

Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join! [FROM com.armbet.ws.domain.entities.SecurityToken st INNER JOIN security_token_types stt ON st.security_token_type_id = stt.security_token_type_id WHERE stt.security_token_type_label = :type AND st.account_id = :accountId]
    at org.hibernate.hql.internal.ast.QuerySyntaxException.convert(QuerySyntaxException.java:74)
    at org.hibernate.hql.internal.ast.ErrorCounter.throwQueryException(ErrorCounter.java:91)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:268)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115)
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76)

我觉得我在SecurityPersistor#findTokensByAccountAndType 方法中的JOIN 语法是错误的。有什么想法会出错吗?

【问题讨论】:

  • 谢谢@pvpkiran 我也看到了,但是如果您阅读问题描述以及单独的答案,您会发现我已经尝试过该解决方案。相同的异常/错误消息,两个不同的问题!

标签: hibernate jpa spring-boot spring-data


【解决方案1】:

另外,不要更改实体名称,如果要指向具有不同名称的表,则使用实体:

@Entity
@Table(name = "security_tokens")
class SecurityToken {
}

而不是

@Entity(name = 'security_tokens')
class SecurityToken {
}

然后查询:

@Query("FROM SecurityToken st where st.type.label = :type AND st.account.id = :accountId")

【讨论】:

  • 感谢@dawid (+1) 我尝试了您的建议,但仍然存在相同的异常。有什么想法吗?
  • 但是我提出的查询没有连接,所以如果你使用它,你就不能拥有:QuerySyntaxException:连接的预期路径! (数据库级别有连接,但 JPQL 级别没有 - 例外情况会有所不同)
  • 啊,很抱歉!剪切 n 粘贴错误!有了你的建议,我得到了Caused by: org.hibernate.QueryException: could not resolve property: account_id of: com.armbet.ws.domain.entities.SecurityToken
  • 再次,请使用st.account.id = :accountId 而不是st.account_id = :accountId - 这是java名称 - 不是sql
  • 剧情变厚了!现在进行最新更改会创建Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: security_tokens is not mapped 异常!这是什么意思(未映射)?!
【解决方案2】:

如果您有 toOne 映射关系,则无需加入。

这个查询应该可以工作:

@Query("FROM security_tokens st WHERE st.type.label = :type AND st.account.id = :accountId")

您应该阅读 JPQL。一个很好的来源是 Hibernate 文档:

http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#hql

【讨论】:

  • 感谢@Simon (+1) 非常感谢!但是,您的建议将例外更改为Caused by: org.hibernate.QueryException: could not resolve property: account_id of: com.armbet.ws.domain.entities.SecurityToken...有什么想法吗?也许将其更改为account
  • 应该是st.account.id
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-12
  • 1970-01-01
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
相关资源
最近更新 更多