有一个用户实体与角色实体有一对多的关系。换句话说,一个用户可以拥有多个角色。无论如何,当我使用JPQL查询时,Role实体显示重复的结果,在这种情况下,它显示ROLE_ADMIN
两次。当我调试代码时,我可以看到Role实体具有相同的内存ID:
[org.huahsin.Role@1b332d22, org.huahsin.Role@1b332d22]
我不确定我是否在JPQL中做错了什么。如果我错了,请纠正我。以下是这个问题的一些提示。
这是Users表中提供的内容:
+----------+----------+---------+
| username | password | enabled |
+----------+----------+---------+
| user7 | user7 | 1 |
+----------+----------+---------+
这是Users表的表格描述:
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(10) | NO | PRI | | |
| password | varchar(32) | YES | | NULL | |
| enabled | int(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
这是授权表中可用的内容:
+----------+------------+
| username | authority |
+----------+------------+
| user7 | ROLE_ADMIN |
| user7 | ROLE_USER |
+----------+------------+
这是授权表的表格描述:
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| username | varchar(10) | NO | MUL | NULL | |
| authority | varchar(10) | NO | | NULL | |
+-----------+-------------+------+-----+---------+-------+
这是关于用户实体的查询:
@NamedQuery(
name="findByUser",
query="select u from User u where u.username in (select r.userId from u.roleList r where r.userId = :username)")
@Entity
@Table(name="users")
public class User {
@Id
private String username;
private String password;
private Integer enabled;
@OneToMany(targetEntity = Role.class, cascade = {CascadeType.ALL})
@JoinColumn(name="username")
private List<Role> roleList;
这是角色实体:
@Entity
@Table(name="authority")
public class Role {
@Id
@Column(name="username")
private String userId;
@Column(name="authority")
private String role;
这是我检索结果的方法:
List<User> l = emf.createEntityManager().createNamedQuery("findByUser", User.class).setParameter("username", username).getResultList();
for( User u : l ) {
System.out.println(u.getUsername());
System.out.println(u.getRoleList());
}
答案 0 :(得分:1)
目前尚不清楚您要通过此查询尝试实现的目标。如果您希望按username
加载用户,并且username
是主键,则可以按以下方式执行:
User u = em.find(User.class, username);
您的Role
实体映射不正确导致结果不正确:userId
注释为@Id
,但它不是主键(即它不是唯一的)。< / p>
我建议你改变数据库架构。 User
和Role
(带连接表)之间的多对多关系将更容易映射:
public class User {
...
@OneToMany
@JoinTable(name = "users_authority")
private List<Role> roleList;
...
}
public class Role {
@Id
private String authority;
}
如果修复了当前的数据库架构,则需要:
authority
username
具有复合键(authority
,@EmbeddedId
)的事实
@MapsId
表示外键authority
(username
)是authority
另见: