我是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);
问题有两个:
我应该“反转” 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表上,看看是否有变化。
答案 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 ?
正确返回我需要的内容。