Как сделать жадную выборку в Spring data?

408
17 августа 2017, 20:51

Есть 2 сущьности User и Role. Мне нужно сделать выборку User что бы Role которая у User на полях тоже инициализировалась.

Что то вроде Hibernate.initialize(User.getRole()).

Или жадной выборки :

from User u join fetch u.role where u.username := username and u.password := password и как-то сделать .setParameter().

Но так как я использую интерфейс CrudRepository<T, ID extends Serializable> то мне надо использовать характерный для Spring Data подход.

Испробовал уже много вариантов не буду захламлять ими вопрос. Но если в 2-х словах все упирается в валидность синтаксиса Query() аннотации для метода:

public interface UserRepository extends CrudRepository<User, Integer> {
    @Query("...?...")
    User findDistinctFirstByUsernameAndPassword(String username, String password);
}

Помогите пожалуйста это решить, наверняка Spring data позволяет это делать, возможно нужно выбрать другой интерфейс или как-то хитро построить запрос..? Спасибо.

Вот мои сущьности:

@Entity(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(name = "username")
    private String username;
    @Column(name = "password")
    private String password;
    @Column(name = "enabled")
    private boolean enabled;
    @OneToMany()
    @JoinColumn(name = "username")
    private List<Role> role;
    ...get & set & constr...
}
@Entity(name = "user_roles")
public class Role {
    @Id
    @Column(name = "user_role_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(name = "username")
    private String username;
    @Column(name = "role")
    private String role;
    ...get & set & constr...
}

UPDATE

Таблицы

CREATE TABLE users (
  id       SERIAL      NOT NULL,
  username VARCHAR(20) NOT NULL,
  password VARCHAR(20) NOT NULL,
  enabled  BOOLEAN     NOT NULL DEFAULT FALSE,
  PRIMARY KEY (username)
);
CREATE TABLE user_roles (
  user_role_id SERIAL PRIMARY KEY,
  username     VARCHAR(20) NOT NULL,
  role         VARCHAR(20) NOT NULL,
  UNIQUE (username, role),
  FOREIGN KEY (username) REFERENCES users (username)
);
Answer 1

Если вам необходимо иногда выбирать жадно, а иногда лениво, и поэтому не подходит указание типа выборки в аннотации @OneToMany(fetch = FetchType.EAGER), то можно попробовать воспользоваться стратегией загрузки графа:

@Entity(name = "users")
@NamedEntityGraph(name = "User.detail", attributeNodes = @NamedAttributeNode("role"))
public class User {
    ...
    @OneToMany()
    @JoinColumn(name = "username")
    private List<Role> role;
    ...
}
public interface UserRepository extends CrudRepository<User, Integer> {
    @EntityGraph(value = "User.detail", type = EntityGraphType.LOAD)
    User findDistinctFirstByUsernameAndPassword(String username, String password);
}
READ ALSO
Hibernate mapping конструкции List&lt;Map&lt;String, String&gt;&gt; list

Hibernate mapping конструкции List<Map<String, String>> list

Как замаппить конструкцию вида List<Map<String, String>> list, используя XML mapping Hibernate?

245
Java - чистый код на примере простого цикла

Java - чистый код на примере простого цикла

Сразу скажу - в java начинающий, как сделать цикл более "грамотным" и "логичным"?

275
Вывод более глубоких элементов в ArrayList

Вывод более глубоких элементов в ArrayList

Как получить(либо вывести в консоль) более глубокое значение ArrayList, например значение testVal из ArrayList-a parserJson, если он всегда имеет динамическую...

242
Алгоритм аутентификации на Rx

Алгоритм аутентификации на Rx

ЗдравствуйтеЕсть следующий код:

191