带有本机查询和数据投影的Spring JPA,将错误的列映射到投影的接口 [英] Spring JPA with native query and data projection mapping the wrong columns into the projected interface

查看:122
本文介绍了带有本机查询和数据投影的Spring JPA,将错误的列映射到投影的接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个奇怪的问题,我不知道为什么会发生.我确定我做错了,因为这是我第一次使用数据投影,而使用DTO从未遇到过此类问题.

I've got a bit of a bizarre problem that I can't figure out why it's happening. I'm sure I did something wrong, because this is my first time using a data projection and I've never had such problems using DTOs.

几乎我有一个SELECT政治家,正在返回各种数据类型的某些列.我有一个接口要传递给JPA存储库,以便它可以进行接口映射.但是,它不是根据列名(例如'accountnum'-> getAccountnumber())映射结果,而是按字母顺序映射列.因此,如果"date_of_order"是SELECT语句中的第一个,则其值将由getAccountnumber()返回.

Pretty much I have a SELECT statemen that is returning certain columns of various data types. And I have an interface that I'm passing to the JPA Repository so it can do the interface mapping. But instead of mapping the results based on the column name (eg. 'accountnum' -> getAccountnumber()), it's mapping the columns in alphabetical order. So if 'date_of_order' is the first in the SELECT statement, its value will be returned by getAccountnumber().

我有一个预计的界面,看起来像这样:

I have a projected interface that looks something like this:

public interface FlatSearchResult {
    String getAccountnumber();
    UUID getTrackingId;
    Date getDateOfOrder;
}

我的模型有三个这样的表:

My model has three tables something like this:

ACCOUNT
  - account_id : uuid (pkey)
  - accountnumber : string
ORDERS
  - order_id : uuid (pkey)
  - date_of_order : timestamp
  - account_id : uuid (fkey)
TRACKING
  - tracking_id : uuid (pkey)
  - order_id : uuid (fkey)

每个表中都有其他列,但它们不相关.

There's other columns in each of those tables, but they're not relevant.

我有一个通过简单查询定义的存储库:

I have a repository defined with a simple query:

public interface OrderTrackingRepository extends JpaRepository<Account, UUID> {
  @Query( nativeQuery = true,
          value = "SELECT o.date_of_order, a.accountnumber, t.tracking_id " +
                  "FROM account as a " +
                  "INNER JOIN orders as o USING (account_id) " +
                  "INNER JOIN tracking as t USING (tracking_id) " +
                  "WHERE a.accountnumber = :acctnum")
  <T> Collection<T> findOrderInfoForAccount(@Param("acctnum") acctNumber, Class<T> type);
}

当我调用此方法时,查询将返回正确的行.但是,它不是使用列名进行映射(例如,date_of_order到getDateOfOrder()),而是基于SELECT语句中的列顺序映射到接口中按字母顺序排序的方法.

When I call this method, the correct rows are returned by the query. But instead of mapping using the column name (eg. date_of_order to getDateOfOrder()), it is mapping based on the order of the columns in the SELECT statement to the alphabetically-ordered methods in the interface.

所以:

SELECT date_of_order, accountnumber, tracking_id

结果:

getAccountNumber() -> date_of_order
getDateOfOrder() -> accountnumber
getTrackingId() -> tracking_id

它将始终以这种方式返回,因此这不是暂时性的问题.

It will consistently return in this fashion, so it's not a transient issue.

作为临时的解决方法,我对SELECT语句中的列进行了重新排序.但是我宁愿不必这样做,因为这就像遍历结果集并依赖列位置一样,这只是让我抽搐而已..

As a temporary workaround, I've reordered the columns in my SELECT statement. But I would rather not have to do this since it's like iterating through a result set and relying on column position, which just makes me twitchy....

如何使Spring JPA从结果集中映射到我的界面?我是否需要在投影接口的方法上添加注释,以告诉Spring它指的是什么列名?

How can I get Spring JPA to map from the result set to my interface? Do I need to annotate my projection interface's methods with something to tell Spring what column name it's referring to?

我的数据库是Postgres.我正在使用Spring 5.0.2.RELEASE和Spring-Boot 2.0.0.M7.如果需要,我可以将其中任何一个调整为较新的版本,但没有较旧的版本.我正在使用C3P0 0.9.5.2进行连接缓冲,并使用postgres-9.2-1002.jdbc4.这个版本的Spring-Boot引入了我所有的其他依赖项(休眠等).

推荐答案

我遇到了同样的问题,我通过按字母顺序排列查询列来解决了这个问题.

I had the same problem and i solved by odering the query columns alphabetically.

在这种情况下:

public interface OrderTrackingRepository extends JpaRepository<Account, UUID> {
  @Query( nativeQuery = true,
          value = "SELECT a.accountnumber, o.date_of_order, t.tracking_id " +
                  "FROM account as a " +
                  "INNER JOIN orders as o USING (account_id) " +
                  "INNER JOIN tracking as t USING (tracking_id) " +
                  "WHERE a.accountnumber = :acctnum")
  <T> Collection<T> findOrderInfoForAccount(@Param("acctnum") acctNumber, Class<T> type);
}

所以您会得到:

getAccountNumber()->帐号 getDateOfOrder()-> date_of_order getTrackingId()-> tracking_id

getAccountNumber() -> accountnumber getDateOfOrder() -> date_of_order getTrackingId() -> tracking_id

这篇关于带有本机查询和数据投影的Spring JPA,将错误的列映射到投影的接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆