1

摘要: Spring Data 发出警告,因为它SELECT是同一列两次。警告是:

(...) WARN o.s.d.j.core.convert.ResultSetAccessor   : ResultSet contains id multiple times

这是spring-boot-starter-data-jdbc通过 Spring Boot 2.5.5(文档)。我正在处理一个非常基本的一对多关系:

在此处输入图像描述

为了简洁起见,我尽可能地减少了实体类,同时保留了警告:

插座.java

(...)
@Table("outlet")
public class Outlet {
    @Id
    private String outletId;
    @MappedCollection(idColumn = "outlet_id", keyColumn = "id")
    private Map<String, OfferedService> offeredServices;
    (...)
}

提供服务.java

(...)
@Table("offered_service")
public class OfferedService {
    @Id
    private String id;
    private String outletId;
    (...)    
}

存储库也是最基本的......

OutletRepository.java

(...)
public interface OutletRepository extends CrudRepository<Outlet, String> {}

...在我的应用程序代码中,我只是findAll在这个存储库上做一个:

(...)
outletRepo.findAll();
(...)

这会导致查询两次选择同一列,随后来自 Spring Data 的警告ResultSetAccessor

DEBUG o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL statement [
    SELECT "outlet"."outlet_id" AS "outlet_id" FROM "outlet"]
DEBUG o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL query
DEBUG o.s.jdbc.core.JdbcTemplate               : Executing prepared SQL statement [
    SELECT "offered_service"."id" AS "id", 
        "offered_service"."outlet_id" AS "outlet_id", 
        "offered_service"."id" AS "id"
    FROM "offered_service"
    WHERE "offered_service"."outlet_id" = ?]
TRACE o.s.jdbc.core.StatementCreatorUtils      : Setting SQL statement parameter value: 
    column index 1, parameter value [xyz012], value class [java.lang.String], SQL type 12
WARN  o.s.d.j.core.convert.ResultSetAccessor   : ResultSet contains id multiple times
WARN  o.s.d.j.core.convert.ResultSetAccessor   : ResultSet contains id multiple times
(...repeated many times...)

我在这里做错了什么?另外,对于findAll,这不应该是 aJOIN吗?

4

1 回答 1

1

您有两件事被映射到 column :从to和 attributeoffered_service.outlet_id的一对多映射。OutletOfferedServiceOfferedService.outletId

如果这些应该不同,您可以使用注释来更改这些映射到的列,但我假设您是故意这样做的,以便outletIdOfferedService实体中使用。

虽然这可行,但它是一种黑客攻击,可能会在未来的版本中中断。

做这样的事情的推荐方法是outletId使用@Transient和使用纯 java 代码来设置它的值,当 anOfferedService添加到Outlet.

有一篇关于此的博客文章:https ://spring.io/blog/2021/09/22/spring-data-jdbc-how-do-i-make-bidirectional-relationships

OfferedService.idSpring Data JDBC 确实选择了两次似乎还有另一个问题。我不确定为什么会这样。对我来说似乎是一个错误。但是您可能可以id完全删除,因为映射键和outlet_id应该形成一个完美的主键。

于 2021-10-18T10:19:28.713 回答