【问题标题】:Spring Data JPA - Using @Query with Many to Many Relationships / Join TableSpring Data JPA - 将@Query 与多对多关系/联接表一起使用
【发布时间】:2018-11-01 10:15:34
【问题描述】:

我有一个用户实体,它与角色实体具有多对多关系。

    @Entity
@Table(name = "auth_user")
public class OAuthUser {

    // @Autowired
    // @Transient
    // private PasswordEncoder passwordEncoder;
    //
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    @Column(name = "username")
    private String userName;

    @Column(name = "password")
    @JsonIgnore
    private String password;

    @Column(name = "first_name")
    private String firstName;

    @Column(name = "last_name")
    private String lastName;

    @Column(name = "email")
    private String email;

    @Column(name = "is_enabled")
    private boolean isEnabled;

    /**
     * Reference:
     * https://github.com/nydiarra/springboot-jwt/blob/master/src/main/java/com/nouhoun/springboot/jwt/integration/domain/User.java
     * Roles are being eagerly loaded here because they are a fairly small
     * collection of items for this example.
     */
    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private List<Role> roles;

    @ManyToMany(fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    @JoinTable(name = "user_properties", joinColumns = @JoinColumn(name = "AuthID", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "PropertyID", referencedColumnName = "id"))
    private List<Property> properties;

我正在使用 Spring Data JPA 存储库,并且能够创建一个自定义 @Query,它根据特定角色 ID 返回用户列表。

    @Query("SELECT u FROM auth_user as u WHERE u.isEnabled AND u.id IN"
        + " (SELECT r.user_id FROM user_role as r WHERE r.role_id = ?1)")
public List<OAuthUser> findByRole(int roleID);

上面的代码导致错误auth_user is not mapped。我确实理解为什么会出现错误;该框架使用实体名称 (OAuthUser) 而不是表 (auth_user) 来执行查询。这通常不会成为问题,除非user_role 没有实体;它只是一个包含两列的连接表:“user_id”和“role_id”。

实现这一目标的适当方法是什么?

谢谢。

【问题讨论】:

  • 希望您没有以明文形式存储密码,但只是未能将字段命名为 passwordHash!

标签: java spring spring-data spring-data-jpa


【解决方案1】:

错误提示:

auth_user 未映射

它指的是SELECT u FROM auth_user等查询中使用的auth_user。在查询中,它必须是 OAuthUser

【讨论】:

  • 谢谢。我明白那个。抱歉,如果我不清楚,但我的问题是如何为 user_role 执行此操作,因为它不是 @Entity,而只是一个连接表?
  • 检查答案here,无需在查询中显式使用连接表。
  • 谢谢。我道歉;我没有意识到这最终会成为重复。作为参考,我的目标的正确查询是@Query("SELECT u FROM OAuthUser as u JOIN u.roles as r WHERE r.id = ?1 AND u.isEnabled = true")
【解决方案2】:

您正在使用 jpql @Query 内部的表名 (auth_user)。您应该改用类名 OAuthUser

@Query("SELECT u FROM OAuthUser u ...")
public List<OAuthUser> findByRole(int roleID);

如果你想使用SQL而不是jpql,你需要这样使用:

@Query(value = "SELECT * FROM auth_user ..." , nativeQuery=true)
public List<OAuthUser> findByRole(int roleID);

这样你就可以提及表名和列。

【讨论】:

  • 虽然我已经以不同的方式解决了它,但感谢您的回答。本机查询选项看起来很有用。我意识到需要使用@Query 中的类名,但使用连接表时没有类名。再次感谢。
猜你喜欢
  • 2018-04-14
  • 2017-08-19
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多