【问题标题】:Query in repository not translated correctly存储库中的查询未正确翻译
【发布时间】:2019-01-29 11:46:40
【问题描述】:

我是 Spring Data 的初学者,我必须编写我的第一个困难查询 :)

我正在为一个活动制作预订引擎。我的数据模型由以下人员组成:

  • RoomType 实体定义了房间的可能配置(例如双人房、三人房、四人房)
  • 代表实际房间的Room 实体
  • 一个RoomArrangement 实体,为Room 定义了所有可能的RoomTypes(例如,房间 7 可以配置为三人房或双人房)
  • RoomAssignment 实体,表示为房间预订后选择的实际配置

FK 以这种方式配置 RoomType <--* RoomArrangement *--> Room <-- RoomAssignment (实体定义见下方代码)

对于给定的RoomType,我需要找到具有最高优先级(= 最接近 1)的AssignmentRoom

我已将 Spring 配置如下。

RoomType.java

@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "room_type_id")
private List<RoomArrangement> roomArrangements;

RoomArrangement.java

@ManyToOne(targetEntity = RoomType.class)
@JoinColumn(name = "room_type_id", nullable = false)
private RoomType roomType;

@ManyToOne(targetEntity = Room.class)
@JoinColumn(name = "room_id", nullable = false)
private Room room;

@Column(name = "priority")
private Integer priority;

Room.java

@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "room_id")
private List<RoomArrangement> roomArrangements;

@OneToOne(fetch = FetchType.LAZY, mappedBy = "room", cascade = CascadeType.ALL)
private RoomAssignment assignment;

RoomArrangementRepository.java

RoomArrangement findFirstByRoomTypeAndRoom_AssignmentIsNullOrderByPriorityAsc(RoomType rt);

上面的查询被翻译成

select 
roomarrang0_.id as id1_3_, 
    roomarrang0_.priority as priority2_3_, 
    roomarrang0_.room_id as room_id3_3_, 
    roomarrang0_.room_type_id as room_typ4_3_ 
from 
room_arrangements roomarrang0_ 
    left outer join 
    rooms room1_ on roomarrang0_.room_id=room1_.id 
where 
    roomarrang0_.room_type_id=9     
    and 
    (room1_.id is null)
order by 
    roomarrang0_.priority asc 
limit 1;

问题有两个:

  1. 不知where子句在哪里 (room1_.id 为空) 来自
  2. 我不知道“AndRoom_AssignmentIsNull”子句去了哪里

我应该“反转” OneToOne 关系并将 FK 放在 Room 类上吗?

感谢您的帮助! 洛伦佐


我已尝试应用一些建议,并“转”了 RoomRepository 上的查询。

查询是这样的:

Room findFirstByRoomArrangements_RoomTypeAndAssignmentIsNullOrderByRoomArrangements_PriorityAsc(RoomType rt);

我们遇到了同样的问题: 选择 room0_.id 为 id1_6_, room0_.room_name 为 room_nam2_6_ 从 房间房间0_ 左外连接 room_arrangements roomarrang1_ on room0_.id=roomarrang1_.room_id 在哪里 roomarrang1_.room_type_id=? 和 (room0_.id 为空) 订购 roomarrang1_.priority asc 限制?;

我认为问题在于 Room 和 RoomAssignment 之间的一对一关系在数据库中表示为 room_assignments 表到 rooms 表的 FK。

我将尝试将 FK 放在 rooms 表而不是 room_assignments 表上,看看是否有变化。

【问题讨论】:

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


    【解决方案1】:

    如果您需要找到一个没有分配的房间,您不应该在房间存储库中查找吗?

    【讨论】:

      【解决方案2】:

      您说您必须找到Room,但您在RoomAssignmentRepository 中返回RoomArrangement。这很令人困惑。

      假设你在正确的地方,这意味着RoomRepository,正如你所说:

      我需要找到对于给定 RoomType 具有最高优先级(= 最接近 1)的没有分配的房间。

      尝试使用以下方法名

      Room findByRoomArrangementRoomTypeAndRoomAssignmentIsNullOrderByPriorityAsc(RoomType rt)

      【讨论】:

      • 问题错误:查询在 RoomArrangement 存储库中,我将尝试此策略。只是,我可能必须按 RoomArrangement_Priority 订购 :)
      • 问题现在是正确的。不幸的是,我选择了两个相似的名字,自己也弄糊涂了:)
      【解决方案3】:

      成功了! 最后,问题在于 Room 和 RoomAssignment 之间的一对一关系是由一个 FK 从 RoomAssignment 映射到 Room 的。显然,Spring Data 没有正确管理这个配置:Assignment is null 被转换为 room_assignment.room_id = null 并且,因为 room_id 是 room.id 的 FK,所以到 room.id = null。

      反转FK映射,查询被翻译成

      select 
          room0_.id as id1_6_, 
          room0_.assignment_id as assignme3_6_, 
          room0_.room_name as room_nam2_6_ 
      from 
          rooms room0_ 
          left outer join room_arrangements roomarrang1_ on room0_.id=roomarrang1_.room_id 
      where 
          roomarrang1_.room_type_id=? 
          and (room0_.assignment_id is null) 
      order by 
          roomarrang1_.priority asc 
      limit ?
      

      它正确地返回了我需要的东西。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-28
        • 2018-12-29
        • 2020-05-18
        • 1970-01-01
        • 1970-01-01
        • 2018-12-24
        • 2010-11-23
        • 2011-12-05
        相关资源
        最近更新 更多