hibernate 为什么在Sping Boot Data JPA中不执行@Query?

rkue9o1l  于 2023-10-23  发布在  其他
关注(0)|答案(2)|浏览(146)

我有一个Repository:

@Repository
public interface UserRequestRepository extends JpaRepository<UserRequestDao, Long> {

@Query("SELECT ur FROM UserRequestDao ur WHERE ur.user.id = ?1")
    //@Query(value = "SELECT * FROM USER_REQUEST WHERE USER_ID = ?1", nativeQuery = true)
    List<UserRequestDao> findAllByUserId(long id);
}

在这两种情况下(第一个@Query和第二个native @Query),Hibernate执行以下查询:

select v1_0.id,v1_0.cel_id,v1_0.user_id,v1_0.instructions,v1_0.occasion from user_request v1_0

即检索所有用户请求。为什么Hibernate忽略了@Query,为什么当我添加@Query注解时,它会检索所有记录?它应该根据用户ID检索记录。
下面是DAO对象:

@Data
@Entity
@Builder
@Table(name = "USER_REQUEST")
@NoArgsConstructor
@AllArgsConstructor
public class UserRequestDao {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private UserDao user;

    @ManyToOne(fetch = FetchType.LAZY)
    private CelebDao celeb;

    private String occasion;
    private String instructions;
}

下面是我调用repository方法的服务类:

@Override
public List<VideoRequest> getAllByUserId(Long id) {
    List<VideoRequestDao> videoRequests = repository.findAllByUserId(userService.get(id).getId());
    return videoRequests.stream().map(ObjectConverter::convertToVideoRequestModel).toList();
}

我试图弄清楚它主要是通过在网上搜索,但找不到解决方案。
有什么想法吗?谢谢

bvhaajcl

bvhaajcl1#

您遇到的@Query annotation在Sping Boot Data JPA中未按预期执行的问题可能与您的UserRequestDao实体中@Query annotation和JPA关联的使用有关。
在您的UserRequestDao实体中,您有两个@ManyToOne关联,user和celeb,标记为FetchType.LAZY。当Hibernate加载带有这些标记为FetchType.LAZY的关联的实体时,除非显式请求,否则它不会立即获取这些关联。在您的查询中,您根据www.example.com过滤记录user.id,它是用户关联的一部分。
要确保@Query按预期执行,您可以执行以下操作:
在加载UserRequestDao实体时错误地获取用户关联:

@ManyToOne(fetch = FetchType.EAGER)
private UserDao user;

将fetch类型改为EAGER,用户关联会在加载UserRequestDao实体时加载,您的@Query将按预期工作。
或者,您可以在@Query中使用JOIN FETCH子句来显式指定应在查询中获取用户关联:

@Query("SELECT ur FROM UserRequestDao ur LEFT JOIN FETCH ur.user WHERE ur.user.id = ?1")
List<UserRequestDao> findAllByUserId(long id);

这个查询包含一个LEFT JOIN FETCH ur.user子句,它告诉Hibernate急切地获取查询中的用户关联。这样,您可以将用户关联的FetchType.LAZY保留在实体中,同时仍然确保在查询需要时加载它。
在进行了这些更改之后,您的@Query应该可以按预期工作,并且Hibernate将根据预期的用户ID检索记录。

yfjy0ee7

yfjy0ee72#

在@Query实现中似乎没有错误,所以我的猜测是,在@Service层上,您必须调用findAll()方法而不是findAllByUserId(long id)。

相关问题