存储库中的查询翻译不正确

时间:2019-01-29 11:46:40

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

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

我正在为事件预订引擎。我的数据模型由以下组成:

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

以这种方式配置FK RoomAssignment (有关实体的定义,请参见下面的代码)

对于给定的RoomType <--* RoomArrangement *--> Room <-- RoomAssignment,我需要找到没有Room的优先级最高(=最接近1)的Assignment

我已经按如下方式配置了Spring。

RoomType.java

RoomType

RoomArrangement.java

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

Room.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;

RoomArrangementRepository.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;

上面的查询被翻译为

RoomArrangement findFirstByRoomTypeAndRoom_AssignmentIsNullOrderByPriorityAsc(RoomType rt);

问题有两个:

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

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

感谢您的帮助! 洛伦佐


我尝试应用一些建议,并在RoomRepository上“打开”查询。

查询如下:

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;

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

我认为问题在于一个事实,即Room和RoomAssignment之间的一对一关系在数据库中用room_assignments表上的FK表示到Rooms表中。

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

3 个答案:

答案 0 :(得分:1)

如果您需要查找没有分配的房间,您是否不应该在“房间”存储库中查找房间?

答案 1 :(得分:1)

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

让我们假设您在正确的位置,这意味着RoomRepository,正如您所说:

  

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

尝试使用以下方法名称

Room findByRoomArrangementRoomTypeAndRoomAssignmentIsNullOrderByPriorityAsc(RoomType rt)

答案 2 :(得分:0)

做到了! 最后,问题在于,FK从RoomAssignment到Room映射了Room和RoomAssignment之间的一对一关系。显然,Spring Data无法正确管理此配置:Assignment为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 ?

正确返回我需要的内容。