mysql spring data jpa `@ pixotyGraph`不按预期工作

2guxujil  于 9个月前  发布在  Mysql
关注(0)|答案(1)|浏览(110)

我在Spring Data Jpa中遇到了一个@EntityGraph的问题,它不能像我预期的那样运行。

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class Board extends BaseTimeEntity {
    @Id @GeneratedValue
    private Long id;

    @JoinColumn(name = "writer_id")
    @ManyToOne(fetch = FetchType.LAZY)
    private User user;

    // others
}

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class User extends BaseTimeEntity {
    @Id @GeneratedValue
    private Long id;

    // others 
}

字符串
这些是简化的实体及其关系。问题在于以下存储库方法:

@Repository
public interface BoardJpaRepository extends JpaRepository<Board, Long> {
    @EntityGraph(attributePaths = {"user"})
    Optional<Board> findById(Long id);
}


我打算在findById方法中使用@ bottyGraph来获取Board和User,但执行的查询只获取Board:

select
    b1_0.id,
    b1_0.content,
    b1_0.create_date,
    b1_0.modified_date,
    b1_0.title,
    b1_0.writer_id,
    b1_0.views 
from
    board b1_0 
where
    b1_0.id in (?,?,?)


此外,当我在BoardRepository中的其他查询方法中使用@ martyGraph时,它按预期工作:

@EntityGraph(attributePaths = {"user"})
Page<Board> findAll(Pageable pageable);

@EntityGraph(attributePaths = {"user"})
@Query("select b from Board b where b.user.username like %:username%")
Page<Board> findAllByUsernameLike(@Param(value = "username") String username, Pageable pageable);

@EntityGraph(attributePaths = {"user"})
@Query("select b from Board b where b.title like %:title%")
Page<Board> findAllByTitleLike(@Param(value = "title") String title, Pageable pageable);

@EntityGraph(attributePaths = {"user"})
@Query("select b from Board b where b.content like %:content%")
Page<Board> findAllByContentLike(@Param(value = "content")
select
        b1_0.id,
        b1_0.content,
        b1_0.create_date,
        b1_0.modified_date,
        b1_0.title,
        u1_0.id,
        u1_0.create_date,
        u1_0.email,
        u1_0.is_account_non_expired,
        u1_0.is_account_non_locked,
        u1_0.is_credentials_non_expired,
        u1_0.is_enabled,
        u1_0.modified_date,
        u1_0.name,
        u1_0.password,
        u1_0.username,
        b1_0.views 
    from
        board b1_0 
    join
        user u1_0 
            on u1_0.id=b1_0.writer_id 
    where
        u1_0.username like concat('%',?,'%') escape '' limit ?,?

我目前的版本是:

  • Java 17
  • Spring Boot 3.1.1
  • Hibernate core 6.2.5.Final

然而,当我将Sping Boot 更新到3.2.0,将Hibernate Core更新到6.3.1.Final时,这个问题似乎得到了解决:

select
        b1_0.id,
        b1_0.content,
        b1_0.create_date,
        b1_0.modified_date,
        b1_0.title,
        u1_0.id,
        u1_0.create_date,
        u1_0.email,
        u1_0.is_account_non_expired,
        u1_0.is_account_non_locked,
        u1_0.is_credentials_non_expired,
        u1_0.is_enabled,
        u1_0.modified_date,
        u1_0.name,
        u1_0.password,
        u1_0.username,
        b1_0.views 
    from
        board b1_0 
    left join
        user u1_0 
            on u1_0.id=b1_0.writer_id 
    where
        b1_0.id=?


查询正确生成,并且由于Spring Batch而声明的in子句似乎也发生了变化。
我不太愿意简单地将其归因于版本问题,因为它感觉不像是一个已解决的问题。我很好奇这是否确实是一个与版本相关的问题,如果是,是否有任何相关的链接或文档?此外,我很想知道是否有针对原始版本的解决方案。

rqqzpn5f

rqqzpn5f1#

我不认为问题出在hibernate版本上,它与fetchtype有关,你正在使用join
如果使用,则将类型作为eager来获取

@JoinColumn(name = "writer_id")
@ManyToOne(fetch = FetchType.EAGER)
private User user

字符串
用户对象将与Board对象一起沿着。
我不知道为什么在6.3.1版本中它是用用户对象来获取的。
如果可以试试

@EntityGraph(attributePaths = {"board.user"})

相关问题