Не удалось лениво инициализировать коллекцию при использовании метода setter для коллекции - PullRequest
0 голосов
/ 01 марта 2019

Я использую метод ниже, чтобы добавить случайных пользователей в группы.Поскольку UserGroup является дочерним, а User является родительским в двунаправленных отношениях, я не использую this.users = users в setter, так как мне нужно сначала удалить текущую группу из всех пользователей, которых нет в списке, а затем добавить текущую группу для пользователей из списка, которыйуже не в этой группе.Однако прохождение userlisToAdd множества пользователей выдает мне ошибку.Инициализация коллекции initializint с помощью вызова this.users = users нарушит мою логику кода, так как мне нужно сначала получить старую коллекцию, чтобы выполнить ее итерацию, но это сделать невозможно, так как коллекция не инициализирована.Какой еще вариант инициализировать коллекцию изнутри сущности в методе setUsers?

Причина: org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекцию роли: it.akademija.wizards.entities.UserGroup.users, не удалось инициализировать прокси-сервер - нет сеанса в org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException (AbstractPersistentCollection.java:597) в org.hibernate.collection.internal.AbstractPersistentCollection.withfileCollection.withfiorg.hibernate.collection.internal.AbstractPersistentCollection.readSize (AbstractPersistentCollection.java:160) в org.hibernate.collection.internal.PersistentSet.size (PersistentSet.java:168) в java.util.HashSet. (HashSet.java:9).) в it.akademija.wizards.entities.UserGroup.setUsers (UserGroup.java:83) в it.akademija.wizards.DataBaseFillerWithFaker.addUsersToGroups (DataBaseFillerWithFaker.java:140) в it.akademija.wizards.DataBaseFillerWithFaker.fillInDatabaseWithData (DataBaseFillerWithFaker.java:52) at it.akademija.wizards.DataBaseFillerWithFaker $$ FastClassBySpringCGLIB $$ f09a7960.invoke () в org.springFlighoxy.progspringframework.: 79) at org.springframework.boot.SpringApplication.callRunner (SpringApplication.java:813) ... пропущено 10 общих кадров

Метод добавления списка пользователей в группу

   @Transactional
   public void addUsersToGroups() {
    List<User> users = userRepository.findAll().stream().filter(user -> !user.isAdmin()).collect(Collectors.toList());
    List<UserGroup> groups = userGroupRepository.findAll();

    for (int i = 0; i < groups.size(); i++) {
        int usersToAdd = (int) Math.floor(Math.random() * users.size() + 1);
        UserGroup userGroup = groups.get(i);

        // Add users to group
        Set<User> usersListToAdd = new HashSet<>();
        for (int y = 0; y < usersToAdd; y++) {
            User user = users.get((int) Math.floor(Math.random() * usersToAdd));
            usersListToAdd.add(user);
        }
        userGroup.setUsers(usersListToAdd);
        // Save group to database
        userGroupRepository.save(userGroup);
    }
}

Сущность группы пользователей

@Entity
public class UserGroup {

    @ManyToMany(mappedBy = "userGroups")
    private Set<User> users;

    public void setUsers(Set<User> users) {
        Set<User> oldUserList = new HashSet<>(this.users);
        oldUserList.stream().filter(user -> !users.contains(user)).forEach(user -> user.removeGroup(this));
        users.stream().filter(user -> !oldUserList.contains(user)).forEach(user -> user.addGroup(this));
    }

}

ComandLineRunner

@Component
public class CommandLineAppRunner implements CommandLineRunner {

// Autowirder classes here

    @Override
    public void run(String... args) throws Exception {

        // Change if you want to fill in databse with random data on startup
        boolean fillInDatabase = true;
        int groups = 12;
        int users = 10000;
        int docTypes = 20;
        int avqDocsForUser = 20;

        // ONLY FOR FIRST RUN WITH EMPTY DATABASE AND FILL IN ENABLED
        if (fillInDatabase
                && roleRepository.count() == 0
                && userRepository.count() == 0
                && userGroupRepository.count() == 0
                && documentRepository.count() == 0
                && documentTypeRepository.count() == 0) {


            dataBaseFillerWithFaker.fillInDatabaseWithData(groups, users, docTypes, avqDocsForUser);
        }

/// Some other unrelated code

Заполнитель базы данных

@Service
public class DataBaseFillerWithFaker {

// Autowired injections

    public void fillInDatabaseWithData(int groups, int users, int docTypes, int avgDocsForUser) {
        addUsersToGroups();
    }

    @Transactional
    public void addUsersToGroups() {
        List<User> users = userRepository.findAll().stream().filter(user -> !user.isAdmin()).collect(Collectors.toList());
        List<UserGroup> groups = userGroupRepository.findAll();

        for (int i = 0; i < groups.size(); i++) {
            int usersToAdd = (int) Math.floor(Math.random() * users.size() + 1);
            UserGroup userGroup = groups.get(i);

            // Add users to group
            Set<User> usersListToAdd = new HashSet<>();
            for (int y = 0; y < usersToAdd; y++) {
                User user = users.get((int) Math.floor(Math.random() * usersToAdd));
                usersListToAdd.add(user);
            }
            userGroup.setUsers(usersListToAdd);
            // Save group to database
            userGroupRepository.save(userGroup);
        }
    }
...