使用setter方法进行收集时,无法延迟初始化收集

时间:2019-03-01 15:19:46

标签: hibernate lazy-initialization

我正在运行以下方法将随机用户添加到组中。由于UserGroup是子级用户,而User是双向关系中的父级,因此我不使用this.users = setter中的用户,因为我需要先从不在列表中的所有用户中删除当前组,然后再从列表中将当前组添加到用户中还没有加入这个群组。但是,传递 userlisToAdd 组用户给我错误。通过调用this.users = Initializint集合,用户将破坏我的代码逻辑,因为我需要首先获取旧的集合以进行迭代,但是这样做并没有初始化集合就不能这样做。还有什么其他方法可以通过setUsers方法从实体内部初始化集合?

  

由以下原因引起:org.hibernate.LazyInitializationException:懒惰   初始化角色集合:   it.akademija.wizards.entities.UserGroup.users无法初始化   代理-没有会话           在org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:597)           在org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:216)           在org.hibernate.collection.internal.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:160)           在org.hibernate.collection.internal.PersistentSet.size(PersistentSet.java:168)           在java.util.HashSet(HashSet.java:119)           在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)           在it.akademija.wizards.DataBaseFillerWithFaker $$ FastClassBySpringCGLIB $$ f09a7960.invoke()           在org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)           在org.springframework.aop.framework.CglibAopProxy $ DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)           在it.akademija.wizards.DataBaseFillerWithFaker $$ EnhancerBySpringCGLIB $$ e5d876d6.fillInDatabaseWithData()           在it.akademija.wizards.CommandLineAppRunner.run(CommandLineAppRunner.java:79)           在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);
    }
}

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);
        }
    }

0 个答案:

没有答案