Search code examples
javaspring-boothibernatespring-data-jpajpql

Join fetch not working for many-to-one associations after migration to 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.


Solution

  • 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)