Количество результатов в методе find()

261
05 октября 2017, 11:17

Имеются три сущности связанных м/ду собой 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() каким-то образом можно изменить?

READ ALSO
Java (MQ). Не запускается imqbrokerd

Java (MQ). Не запускается imqbrokerd

Для посыла сообщений мне требуется открыть брокер на GlassfishОднако при открытии выводится следующее окно:

444
Что из указанного о классах-наследниках верно? [требует правки]

Что из указанного о классах-наследниках верно? [требует правки]

Класс-наследник может наследоваться только от одного родительского класса и может реализовать только один интерфейс

286
Заполнить массив числами от 1000 до 10000-1

Заполнить массив числами от 1000 до 10000-1

Добрый день! Создаю массив целочисленных значений, в него через for при старте программы должны заноситься значения от 1000 до 9999 включительноЗатем...

265