【问题标题】:Inner Join query and interface based Projection in Spring Data JPASpring Data JPA 中的内连接查询和基于接口的投影
【发布时间】:2019-02-26 16:56:53
【问题描述】:

我正在使用运行 MySql DB 的 Spring Data JPA 开发一个 Spring MVC 项目,其中我有四个实体对象:Travel、Expense、Currency 和 Fund。

这是我的数据库架构的可视化表示:

在 ExpenseRepository 接口中我扩展了 JpaRepository 接口。

现在我正在尝试运行本机 SQL 查询,我将在其中传递费用 ID,然后从 Expense 表中获取费用和金额,并从货币表中获取 currency_name。 (你可以看到我必须做两个内连接才能得到currency_name。)

最后我创建了另一个接口 ExpenseOutput 来将三列合并为一个单独的非实体接口(根据 Spring Data JPA 文档中提到的基于接口的投影映射)。

代码如下:

package com.binarycraftbd.ksktravelbackend.Repo

import com.binarycraftbd.ksktravelbackend.JoinQueries.ExpenseData
import com.binarycraftbd.ksktravelbackend.Model.Expense
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query

interface ExpenseRepo : JpaRepository<Expense, Int> {


    @Query("select expense, amount from expense, currencyName from currency inner join fund on expense.fund_id=fund.id inner join currency on fund.currency_id=currency.id where expense.id=?1", nativeQuery = true)
    fun getCurrencyByExpId(expId:Int): ExpenseOutput

    interface ExpenseOutput{
        fun getExpense():String
        fun getAmount(): String
        fun getCurrencyname(): String
    }
}

但是,当我通过 RestController 函数运行代码时,我收到以下错误:

This application has no explicit mapping for /error, so you are seeing this as a fallback.

Sat Sep 22 20:51:25 BDT 2018
There was an unexpected error (type=Internal Server Error, status=500).
could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

我也在这里给出实体类:

旅游类

@Entity
@Table(name = "travel")
class Travel(
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        val id: Int=0,
        val travelName: String="",

        @OneToMany(mappedBy = "travel")
        @JsonIgnore
        val funds: List<Fund> ?= null,

        @OneToMany(mappedBy = "travel")
        @JsonIgnore
        val expenses: List<Expense>?=null

)

货币类别

@Entity
@Table(name = "currency")
class Currency(

        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        val id: Int=0,
        val currencyName: String="",

        @OneToMany(mappedBy = "currency")
        @JsonIgnore
        val funds: List<Fund>?=null
)

基金类

@Entity
class Fund(
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        val id:Int=0,
        val fundName:String="",

        @OneToMany(mappedBy = "fund")
        @JsonIgnore
        val expenses: List<Expense>?= null,

        @ManyToOne
        val travel: Travel?=null,

        @ManyToOne
        val currency:Currency?=null
)

费用类

@Entity
class Expense(


        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE)
        val id:Int=0,
        val date:String="",
        val time:String="",
        val expense:String="",
        val amount:String="",
        val category:String="",

        @ManyToOne
        val travel: Travel?=null,

        @ManyToOne
        val fund: Fund?=null
)

如何解决这个问题?在 ExpenseRepository 中写查询代码不正确吗?还是 Sql 查询有问题?请帮忙!!

【问题讨论】:

  • SQLGrammarException 建议查询语法错误
  • 我已按照 Mohammed Hassan 的建议更正了 SQL 查询。还是没有解决

标签: mysql spring kotlin spring-data-jpa


【解决方案1】:

Econ 尝试在任何 sql 客户端(例如 mysql 工作台)中运行此查询,然后再将其嵌入代码中。

我像下面这样重写了上面的查询,我发现了一些语法错误和不合逻辑的东西。

select expense.expense, expense.amount, currency.currency_name  
from expense inner join fund on (expense.fund_id=fund.id)
inner join currency on (fund.currency_id=currency.id)
where expense.id=<replace this segment with a valid expenseId>

【讨论】:

    猜你喜欢
    • 2020-02-13
    • 1970-01-01
    • 2020-01-10
    • 2019-09-26
    • 1970-01-01
    • 2021-06-19
    • 2015-12-23
    • 2021-01-01
    • 2022-12-02
    相关资源
    最近更新 更多