Spring 不映射角色集

问题描述 投票:0回答:1

我使用 Spring 框架,在从多对多表映射角色集时遇到问题。让我向您展示我的课程。

public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NonNull
    private String authority;

    @ManyToMany(mappedBy = "roles", fetch = FetchType.EAGER/*, cascade=CascadeType.MERGE*/)
    private Set<AppUser> appUsers;

    public Role(@NonNull String authority) {
        this.authority = authority;
    }

    public Role() {

    }
}
public class AppUser implements Serializable {
    @Serial
    private static final long serialVersionUID = -8357820005040969853L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    //    @NonNull
    @Column(unique = true)
    private /*final*/ String username;

    //    @NonNull
    private /*final*/ String password;

    @ManyToMany(fetch = FetchType.EAGER/*, cascade=CascadeType.MERGE*/)
//    @NonNull
    @JoinTable(name = "users_roles",
            joinColumns = @JoinColumn(name = "role_id"/*, referencedColumnName = "id"*/),
            inverseJoinColumns = @JoinColumn(name = "user_id"/*, referencedColumnName = "id"*/))
    private Set<Role> roles;
    }

以下是保存过程:

    @Bean
//    @Transactional
    public CommandLineRunner run(RoleRepository roleRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
        return args -> {
            if (roleRepository.findByAuthority("ADMIN").isEmpty()) {
                Role admin = roleRepository.save(new Role("ADMIN"));
                Role user = roleRepository.save(new Role("USER"));

                userRepository.save(new AppUser("admin", passwordEncoder.encode("admin"), new HashSet<>() {
                    {
                        add(admin);
                        add(user);
                    }
                }));
            }
        };
    }

这是我想要检索用户角色的时刻:

@Component
public class UserInterceptor implements HandlerInterceptor {
    private final UserRepository userRepository;
    private final RoleRepository roleRepository;

    public UserInterceptor(UserRepository userRepository, RoleRepository roleRepository) {
        this.userRepository = userRepository;
        this.roleRepository = roleRepository;
    }

    @Override
    public void postHandle(@NonNull HttpServletRequest request,
                           @NonNull HttpServletResponse response,
                           @NonNull Object handler,
                           ModelAndView modelAndView) {
        if (modelAndView != null) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            Optional<AppUser> appUser = userRepository.findByUsername(authentication.getName());

            if (appUser.isPresent()) {
                Set<Role> set = roleRepository.findByAppUsers(new HashSet<>() {
                    {
                        add(appUser.get());
                    }
                });
                log.info("Roles for user {}: {}", appUser.get().getUsername(), appUser.get().getRoles());
                modelAndView.addObject("username", appUser.get().getUsername());
                modelAndView.addObject("roles", appUser.get().getRoles());
            } else
                modelAndView.addObject("username", "anonymous");
        }
    }
}

最有趣的部分是,当我以“admin”身份使用密码“admin”登录系统时,它会在数据库中看到我的用户,并且我实际上在可选 appUser 中具有值。检查存在后,我创建简单的集只是为了检查它是否映射特定用户的角色,之后我就拥有了由 User 对象检索的角色集。

现在神奇的部分来了:如果我尝试从执行 appUser.get().getRoles() 的用户获取角色,我会在 appUser 对象中得到空的角色集。我的意思是,我可以尝试使用由 userRepository.findByUsername 创建的额外集来获取所有角色,但我觉得它不应该以这种方式工作。任何人都可以帮助我吗,我将不胜感激,它将帮助我获得 Spring 框架。提前致谢。 附:这是数据库中的表,是的,列名弄乱了,我已经修复了它。

java spring database spring-boot many-to-many
1个回答
0
投票

您似乎在 Hibernate 中遇到了延迟初始化问题,特别是在获取集合时发生。

您可以使用

@Fetch(FetchMode.JOIN)
将获取策略从惰性更改为急切。

@ManyToMany(fetch = FetchType.EAGER)
@Fetch(FetchMode.JOIN)
@JoinTable(name = "users_roles",
        joinColumns = @JoinColumn(name = "role_id"),
        inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<Role> roles;

请注意,应谨慎执行此操作,因为它可能会产生许多影响,例如性能下降。

© www.soinside.com 2019 - 2024. All rights reserved.