Join fetch not working for many-to-one associations after migration to Hibernate 6.

huangapple go评论60阅读模式
英文:

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 = &quot;hotel_room&quot;)
@Getter
@Setter
public class HotelRoomEntity implements Serializable {

	@EmbeddedId
	private HotelRoomId id;
}
@Embeddable
@Data
public class HotelRoomId implements Serializable {

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = &quot;hotel_code&quot;, referencedColumnName = &quot;hotel_code&quot;)
	private HotelEntity hotel;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = &quot;room_type_code&quot;, referencedColumnName = &quot;room_type_code&quot;)
	private RoomTypeEntity roomType;
}
@Entity
@Table(name = &quot;room_type&quot;)
@Getter
@Setter
public class RoomTypeEntity implements Serializable {

	@Id
	@Column(name = &quot;room_type&quot;)
	private String code;

	@Column(name = &quot;instance_id&quot;)
	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&lt;HotelRoomEntity, HotelRoomId&gt; {

	@Query(&quot;&quot;&quot;
		select hotelRoom
		from HotelRoomEntity hotelRoom
		join fetch hotelRoom.id.roomType
		where hotelRoom.id.hotel.code = :hotelCode&quot;&quot;&quot;)
	List&lt;HotelRoomEntity&gt; find(@Param(&quot;hotelCode&quot;) 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)

huangapple
  • 本文由 发表于 2023年3月9日 17:28:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/75682659.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定