Spring Data JPA如何通过关联对象UserDetails的name查询User
解决Spring Data JPA通过关联实体属性查询主实体的问题
先理清楚你的实体关联逻辑:User和UserDetails是双向一对一关联,User持有userDetails属性,而你要查询的name字段属于UserDetails。直接写findByName报错,是因为User实体本身并没有name属性,Spring Data JPA没法解析这个不存在的字段。
下面给你两种实用的解决方案:
方案一:遵循Spring Data JPA方法命名规则
你需要通过关联属性导航到目标字段,有两种合法的写法都能被JPA正确解析:
写法1:下划线分隔关联属性与目标属性
在UserRepository里添加这个方法即可:
List<User> findByUserDetails_Name(String name);
写法2:驼峰式拼接关联属性与目标属性
也可以直接用驼峰拼接属性名,效果完全一致:
List<User> findByUserDetailsName(String name);
原理很简单:JPA会自动识别方法名里的UserDetails对应User实体的userDetails属性,然后导航到该属性下的name字段执行查询。
方案二:用@Query自定义JPQL查询
如果方法命名太长或者查询逻辑复杂,推荐直接写JPQL语句,可读性更强:
@Repository public interface UserRepository extends JpaRepository<User, Long> { @Query("SELECT u FROM User u JOIN u.userDetails ud WHERE ud.name = :name") List<User> findUsersByUserDetailsName(@Param("name") String name); }
这里通过JOIN关联User和UserDetails,用ud.name匹配传入的参数,@Param用来绑定方法参数和JPQL里的变量名。
补充小提示
因为你的关联设置了FetchType.LAZY,使用JOIN会触发关联实体的加载(临时转为EAGER)。如果想保持懒加载且只查询User实体,也可以写成:
@Query("SELECT u FROM User u WHERE u.userDetails.name = :name") List<User> findUsersByUserDetailsName(@Param("name") String name);
JPA会自动处理关联查询逻辑,结果和上面一致。
内容的提问来源于stack exchange,提问作者janssen-dev
相关产品推荐
相关产品推荐

