英文:
Join fetch not working for many-to-one associations after migration to Hibernate 6
问题
我们正在将我们的应用程序迁移到Spring Boot 3.0.3和Hibernate 6.1.7,注意到一个影响到带有join fetch子句的查询的变化,当抓取的实体通过多对一关系加入时。我们正在使用Spring Data JPA。
例如,我们有一个HotelRoom实体,它与RoomType有多对一关系:
@Entity
@Table(name = "hotel_room")
@Getter
@Setter
public class HotelRoomEntity implements Serializable {
@EmbeddedId
private HotelRoomId id;
}
@Embeddable
@Data
public class HotelRoomId implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "hotel_code", referencedColumnName = "hotel_code")
private HotelEntity hotel;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "room_type_code", referencedColumnName = "room_type_code")
private RoomTypeEntity roomType;
}
@Entity
@Table(name = "room_type")
@Getter
@Setter
public class RoomTypeEntity implements Serializable {
@Id
@Column(name = "room_type")
private String code;
@Column(name = "instance_id")
private Long instanceId;
}
而且,我们有以下存储库来检索一组HotelRoomEntity以及它们相关的RoomTypeEntities:
@Repository
public interface HotelRoomJpaRepository extends CrudRepository<HotelRoomEntity, HotelRoomId> {
@Query("select hotelRoom from HotelRoomEntity hotelRoom join fetch hotelRoom.id.roomType where hotelRoom.id.hotel.code = :hotelCode")
List<HotelRoomEntity> find(@Param("hotelCode") final int hotelCode);
}
在将Hibernate 6更改之前,这会生成以下查询,一切正常:
select hotelroome0_.hotel_code as hotel_code_19_0_,
hotelroome0_.room_type_code as room_type_code_19_0_,
roomtypeen1_.instance_id as instance_id2_25_1_
from HOTEL_ROOM hotelroome0_
inner join ROOM_TYPE roomtypeen1_
on hotelroome0_.room_type_code=roomtypeen1_.room_type_code
where hotelroome0_.hotel_code=?
现在,使用Hibernate 6,我们得到以下查询,RoomTypeEntity没有被抓取:
select h1_0.hotel_code,
h1_0.room_type_code
from HOTEL_ROOM h1_0
join ROOM_TYPE r1_0
on r1_0.room_type_code=h1_0.room_type_code
where hotel_code=?
为了再次获取相关的实体,我们必须在select子句中添加roomType:
select hotelRoom, roomType
from HotelRoomEntity hotelRoom
join fetch hotelRoom.id.roomType roomType
where hotelRoom.id.hotel.code = :hotelCode
这在Hibernate 6中现在是强制的吗?我没有在任何地方找到这个文档化。
英文:
We are on the process of migrating our apps to Spring Boot 3.0.3 and Hibernate 6.1.7 and noticed a change that affects to queries with join fetch clauses when the fetched entity is joined through a many-to-one relationship. We are using Spring Data JPA.
As a example we got the HotelRoom entity which has a many-to-one relationship with RoomType:
@Entity
@Table(name = "hotel_room")
@Getter
@Setter
public class HotelRoomEntity implements Serializable {
@EmbeddedId
private HotelRoomId id;
}
@Embeddable
@Data
public class HotelRoomId implements Serializable {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "hotel_code", referencedColumnName = "hotel_code")
private HotelEntity hotel;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "room_type_code", referencedColumnName = "room_type_code")
private RoomTypeEntity roomType;
}
@Entity
@Table(name = "room_type")
@Getter
@Setter
public class RoomTypeEntity implements Serializable {
@Id
@Column(name = "room_type")
private String code;
@Column(name = "instance_id")
private Long instanceId;
}
And we have the following repository to retrieve a list of HotelRoomEntity along with their related RoomTypeEntities:
@Repository
public interface HotelRoomJpaRepository extends CrudRepository<HotelRoomEntity, HotelRoomId> {
@Query("""
select hotelRoom
from HotelRoomEntity hotelRoom
join fetch hotelRoom.id.roomType
where hotelRoom.id.hotel.code = :hotelCode""")
List<HotelRoomEntity> find(@Param("hotelCode") final int hotelCode);
}
Prior to the change to Hibernate 6, this generated the following query and all worked fine:
select hotelroome0_.hotel_code as hotel_code_19_0_,
hotelroome0_.room_type_code as room_type_code_19_0_,
roomtypeen1_.instance_id as instance_id2_25_1_
from HOTEL_ROOM hotelroome0_
inner join ROOM_TYPE roomtypeen1_
on hotelroome0_.room_type_code=roomtypeen1_.room_type_code
where hotelroome0_.hotel_code=?
Now, with Hibernate 6, we getting the following query and RoomTypeEntity is not fetched:
select h1_0.hotel_code,
h1_0.room_type_code
from HOTEL_ROOM h1_0
join ROOM_TYPE r1_0
on r1_0.room_type_code=h1_0.room_type_code
where hotel_code=?
For the related entity to be fetched again we must add roomType in the select clause:
select hotelRoom, roomType
from HotelRoomEntity hotelRoom
join fetch hotelRoom.id.roomType roomType
where hotelRoom.id.hotel.code = :hotelCode
Is this mandatory now with Hibernate 6? Haven't found this documented anywhere.
答案1
得分: 0
似乎是 Hibernate 6 中的问题。发生在嵌入式ID关联中。
https://hibernate.atlassian.net/browse/HHH-15875
在版本6.2中已经解决(仍在开发中)。
英文:
Seems it is an issue in Hibernate 6. Happens with embeddedId associations.
https://hibernate.atlassian.net/browse/HHH-15875
It is addressed in version 6.2 (still in development)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论