2013-12-11 1 views
0

Существует пользовательский объект, имеющий отношения «один ко многим» с объектом роли. Другими словами, один пользователь может иметь несколько ролей. Во всяком случае, когда я запрашиваю использование JPQL, объект Role показывает повторяющиеся результаты, в этом случае он показывает ROLE_ADMIN дважды. Когда я отладки кода, я могу видеть, что роль объект, имеющий такой же идентификатор памяти:Как запросить отношения «один ко многим» в JPQL?

[[email protected], [email protected]] 

Я не был уверен, были ли я сделал что-то неправильно в JPQL. Пожалуйста, поправьте меня, если я ошибаюсь. Ниже перечислены некоторые намеки на эту проблему.


Это содержание доступно в таблице пользователей:

+----------+----------+---------+ 
| 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 |  | 
+----------+-------------+------+-----+---------+-------+ 

Это содержание доступно в Authority таблице:

+----------+------------+ 
| username | authority | 
+----------+------------+ 
| user7 | ROLE_ADMIN | 
| user7 | ROLE_USER | 
+----------+------------+ 

Это t он таблица описания для Authority таблицы:

+-----------+-------------+------+-----+---------+-------+ 
| 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:

@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

При отладке кода, вы видите одну и ту же запись роли дважды. Где вы их видите? Также: рассмотрите возможность установления двусторонних отношений и хеширования паролей в БД. –

+0

@AndreiI У меня есть обновление списка кодов в конце вопроса. – huahsin68

+0

Это довольно ясно для меня: это означает, что в вашей БД у вас есть одна и та же роль, связанная дважды. –

ответ

1
  • Непонятно, чего вы пытаетесь достичь по этому запросу. Если вы хотите загрузить пользователя в соответствии с его username и username является первичным ключом, вы можете сделать это следующим образом:

    User u = em.find(User.class, username); 
    
  • Вы получаете неправильные результаты, потому что ваш Role объект отображается неправильно: userId помечается, как @Id , но это не первичный ключ (т. е. он не уникален).

Я предлагаю вам изменить схему базы данных.Многие-ко-многим между 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

Смотрите также:

+0

В моем вопросе я добавил описание таблицы. Он показывает, что у меня есть первичный ключ в таблице пользователя и внешний ключ в таблице полномочий. Эти 2 таблицы используют 'username' как ключ к установлению отношений. – huahsin68

+0

Вы поняли, что 'userId' аннотируется как @Id, но это не первичный ключ. Я решил эту проблему, добавив новый столбец первичного ключа в объект Role. Большая помощь. – huahsin68

Смежные вопросы