Имеются три сущности связанных м/ду собой many-to-many:
public class User {
//...
@ManyToMany(fetch = FetchType.EAGER)
// @ManyToMany
@JoinTable(name = "users_groups",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "group_id")
)
@Getter @Setter
private List<Group> groups;
//...
}
public class Group {
//....
@Getter @Setter
@ManyToMany(fetch = FetchType.EAGER)
// @ManyToMany
@JoinTable(name = "roles_groups",
joinColumns = @JoinColumn(name = "group_id"),
inverseJoinColumns = @JoinColumn(name = "role_id")
)
private List<Role> roles;
//....
}
public class Role {
//...
}
Вот метод поиска по id:
@Transactional(readOnly = true)
public T find (Object id) {
CriteriaBuilder cb = getSessionFactory().getCurrentSession().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(entityClass);
Root<T> t = cq.from(entityClass);
cq.select(t);
cq.where(cb.equal(t.get("id"), id));
return (T) getSessionFactory().getCurrentSession().createQuery(cq).getSingleResult();
// return getSessionFactory().getCurrentSession().find(entityClass, id);
}
Запускаю следующий код:
User user = facade.find(1L);
System.out.println(user.getUsername());
if (user.getGroups() == null) {
System.out.println("\tGroups is null");
} else {
System.out.println("\tGroups count " + user.getGroups().size());
for (Group g : user.getGroups()) {
System.out.println("\t\t"+g.getGroupname());
System.out.println("\t\t\tRoles count " + g.getRoles().size());
for (Role r : g.getRoles()) {
System.out.println("\t\t\t\t"+r.getRolename());
}
}
}
Все ок:
Hibernate: select user0_.id as id1_9_, user0_.password as password2_9_, user0_.username as username3_9_ from users user0_ where user0_.id=1
Hibernate: select groups0_.user_id as user_id1_10_0_, groups0_.group_id as group_id2_10_0_, group1_.id as id1_3_1_, group1_.groupname as groupnam2_3_1_ from users_groups groups0_ inner join groups group1_ on groups0_.group_id=group1_.id where groups0_.user_id=?
Hibernate: select roles0_.group_id as group_id1_6_0_, roles0_.role_id as role_id2_6_0_, role1_.id as id1_5_1_, role1_.rolename as rolename2_5_1_ from roles_groups roles0_ inner join roles role1_ on roles0_.role_id=role1_.id where roles0_.group_id=?
Hibernate: select roles0_.group_id as group_id1_6_0_, roles0_.role_id as role_id2_6_0_, role1_.id as id1_5_1_, role1_.rolename as rolename2_5_1_ from roles_groups roles0_ inner join roles role1_ on roles0_.role_id=role1_.id where roles0_.group_id=?
admin
Groups count 2
admins
Roles count 3
ROLE_USER_ADMIN
ROLE_GROUP_ADMIN
ROLE_ROLE_ADMIN
users
Roles count 1
USER
Но если воспользоваться таким методом find():
@Transactional(readOnly = true)
public T find (Object id) {
// CriteriaBuilder cb = getSessionFactory().getCurrentSession().getCriteriaBuilder();
// CriteriaQuery cq = cb.createQuery(entityClass);
// Root<T> t = cq.from(entityClass);
// cq.select(t);
// cq.where(cb.equal(t.get("id"), id));
// return (T) getSessionFactory().getCurrentSession().createQuery(cq).getSingleResult();
return getSessionFactory().getCurrentSession().find(entityClass, id);
}
то в вывод будет следующим:
Hibernate: select user0_.id as id1_9_0_, user0_.password as password2_9_0_, user0_.username as username3_9_0_, groups1_.user_id as user_id1_10_1_, group2_.id as group_id2_10_1_, group2_.id as id1_3_2_, group2_.groupname as groupnam2_3_2_, roles3_.group_id as group_id1_6_3_, role4_.id as role_id2_6_3_, role4_.id as id1_5_4_, role4_.rolename as rolename2_5_4_ from users user0_ left outer join users_groups groups1_ on user0_.id=groups1_.user_id left outer join groups group2_ on groups1_.group_id=group2_.id left outer join roles_groups roles3_ on group2_.id=roles3_.group_id left outer join roles role4_ on roles3_.role_id=role4_.id where user0_.id=?
admin
Groups count 4
admins
Roles count 3
ROLE_USER_ADMIN
ROLE_GROUP_ADMIN
ROLE_ROLE_ADMIN
admins
Roles count 3
ROLE_USER_ADMIN
ROLE_GROUP_ADMIN
ROLE_ROLE_ADMIN
admins
Roles count 3
ROLE_USER_ADMIN
ROLE_GROUP_ADMIN
ROLE_ROLE_ADMIN
users
Roles count 1
USER
Вся выборка теперь уместилась в один запрос, а листе user.getGroups() теперь содержится 4 элемента (3 группы admins, по числу roles) Подскажите, плиз, такое поведение метода find() каким-то образом можно изменить?
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Для посыла сообщений мне требуется открыть брокер на GlassfishОднако при открытии выводится следующее окно:
Класс-наследник может наследоваться только от одного родительского класса и может реализовать только один интерфейс
Добрый день! Создаю массив целочисленных значений, в него через for при старте программы должны заноситься значения от 1000 до 9999 включительноЗатем...