Hibernate @ManyToMany不保存到第三个表

时间:2016-11-20 22:52:49

标签: java mysql hibernate

用户具有角色,并且具有设置角色:

班级用户

  @Entity
    @Table(name = "users")
    public class User extends BaseEntity {

        @Column(name = "username")
        private String username;

        @Column(name = "password")
        private String password;

        @Transient
        private String confirmPassword;

        @ManyToMany(fetch = FetchType.EAGER)
        @JoinTable(name = "user_roles", joinColumns = @JoinColumn(name = "user_id"),
                inverseJoinColumns = @JoinColumn(name = "role_id"))
        private Set<Role> roles = new HashSet<>();

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public String getConfirmPassword() {
            return confirmPassword;
        }

        public void setConfirmPassword(String confirmPassword) {
            this.confirmPassword = confirmPassword;
        }

        public Set<Role> getRoles() {
            return roles;
        }

        public void setRoles(Set<Role> roles) {
            this.roles = roles;
        }

        @Override
        public String toString() {
            return "User{" +
                    "username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", confirmPassword='" + confirmPassword + '\'' +
                    ", roles=" + roles +
                    '}';
        }
    }

班级角色

@Entity
@Table(name = "roles")
public class Role extends NamedEntity {

    @ManyToMany(mappedBy = "roles")
    private Set<User> users = new HashSet<>();

    public Set<User> getUsers() {
        return users;
    }

    public void setUsers(Set<User> users) {
        this.users = users;
    }
}

-- Table: users
CREATE TABLE users (
  id       INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(255) NOT NULL,
  password VARCHAR(255) NOT NULL
)
  ENGINE = InnoDB;

-- Table: roles
CREATE TABLE roles (
  id   INT          NOT NULL AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL
)
  ENGINE = InnoDB;

-- Table for mapping user and roles: user_roles
CREATE TABLE user_roles (
  user_id INT NOT NULL,
  role_id INT NOT NULL,

  FOREIGN KEY (user_id) REFERENCES users (id),
  FOREIGN KEY (role_id) REFERENCES roles (id),

  UNIQUE (user_id, role_id)
)
  ENGINE = InnoDB;

存储库类:

JpaUserRepositoryImpl

@Repository
@Transactional
public class JpaUserRepositoryImpl implements UserRepository {

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public void registerUser(User user) {
        Session session = this.sessionFactory.openSession();

        session.saveOrUpdate(user);
        session.close();

    }

    public User findUserByUsername(String username) {
        Session session = this.sessionFactory.openSession();

        User user;
        Query query = session.createQuery("SELECT DISTINCT user FROM User user WHERE user.username LIKE :username");
        query.setParameter("username", username + "%");
        user = (User) query.getSingleResult();
        session.close();
        return user;
    }

    public User findUserById(Long id) {
        Session session = this.sessionFactory.openSession();
        User user = session.get(User.class, id);
        session.close();

        return user;
    }
}

JpaRoleRepositoryImpl

@Repository
@Transactional
public class JpaRoleRepositoryImpl implements RoleRepository {

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Role findRoleById(Long id) {
        Session session = this.sessionFactory.openSession();
        Role role = session.get(Role.class, id);
        session.close();
        return role;
    }

    public Role findRoleByName(String name) {
        Session session = this.sessionFactory.openSession();
        Query query = session.createQuery("SELECT role FROM Role role WHERE role.name =:name");
        query.setParameter("name", name);
        Role role = (Role) query.getSingleResult();
        session.close();
        return role;
    }
}

UserServiceImpl

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    JpaUserRepositoryImpl userRepository;

    @Autowired
    RoleServiceImpl roleRepository;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;


    public void registerUser(User user) {
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));

        Set<Role> roles = new HashSet<>();
        roles.add(roleRepository.findRoleById(1L));
        user.setRoles(roles);
        System.out.println(user);
        userRepository.registerUser(user);
    }

    public User findUserByUsername(String username) {
        User user = userRepository.findUserByUsername(username);
        return user;
    }

    public User findUserById(Long id) {
        User user = userRepository.findUserById(id);
        return user;
    }
}

创建新用户后,我在表用户中使用它,但表user_roles中没有更改。 无法理解为什么。 有任何想法吗? 谢谢。

1 个答案:

答案 0 :(得分:0)

在这里,您希望将userUser_roles表的插入操作级联,但您还没有在映射中提供cascade策略。

默认情况下,级联策略是&#34; none&#34;即,不会将任何更改传播到子表。

尝试在映射中应用级联选项,它应该可以工作。

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)

我使用了CAscadeType.ALL,但您可以将其限制为仅插入或更新或删除或任何组合。