简体   繁体   English

使用ManyToOne关系时,Hibernate user_roles表不会更新

[英]Hibernate user_roles table will not update when using ManyToOne relationship

I have 3 tables, User, Role, and User_role. 我有3个表,User,Role和User_role。 User has a OneToMany relationship mapped by "user" with a CascadeType.Merge and user_role has 2 ManyToOne Relationships with cascadeTypes.All however the user_table never populates with data when running hibernate. 用户具有由“用户”与CascadeType映射的OneToMany关系。合并和user_role具有2个具有层叠类型的ManyToOne关系。但是,在运行休眠状态时,user_table永远不会填充数据。 Instead values are only populated in the user and role tables, but never the user_role table. 而是仅在用户表和角色表中填充值,而不填充user_role表中的值。

User Table Definition 用户表定义

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="Id", nullable=false, updatable = false)
private Long id;

private String username;
private String password;
private String firstName;
private String lastName;

private String email;
private String phone;
private boolean enabled = true;

@OneToMany(mappedBy = "user", cascade=CascadeType.MERGE, fetch = 
FetchType.EAGER)
@JsonIgnore
private Set<UserRole> userRoles = new HashSet<>();

UserRole Table: UserRole表:

@Entity
@Table(name="user_role")
public class UserRole implements Serializable {
private static final long serialVersionUID = 890345L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long userRoleId;

@ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL, 
optional=false)
@JoinColumn(name = "user_id")
private User user;

@ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL,  
optional=false)
@JoinColumn(name = "role_id")
private Role role;

public UserRole () {}

public UserRole (User user, Role role) {
    this.user = user;
    this.role = role;
}

public long getUserRoleId() {
    return userRoleId;
}

public void setUserRoleId(long userRoleId) {
    this.userRoleId = userRoleId;
}

public User getUser() {
    return user;
}

public void setUser(User user) {
    this.user = user;
}

public Role getRole() {
    return role;
}

public void setRole(Role role) {
    this.role = role;
}

}

Call To userRepository.save() in userServiceImpl that is called from a commandLine Runner. 从命令行运行器调用到userServiceImpl中的userRepository.save()。

@Service

public class UserServiceImpl implements UserService { 公共类UserServiceImpl实现UserService {

private static final Logger LOG = LoggerFactory.getLogger(UserSecurityService.class);


@Autowired
private UserRepository userRepository;

@Autowired
private RoleRepository roleRepository;


// Indicates a  Database Transaction
@Transactional
public User createUser(User user, Set<UserRole> userRoles) {
    User localUser = userRepository.findByUsername(user.getUsername());

    if(localUser != null) {
        LOG.info("User with username {} already exist. Nothing will be done. ", user.getUsername());
    } else {


        for (UserRole ur : userRoles) {
            roleRepository.save(ur.getRole());
        }

        Set<UserRole> currentRoles =user.getUserRoles();

        currentRoles.addAll(userRoles);
        user.setUserRoles(currentRoles);


        localUser = userRepository.save(user);
    }

    return localUser;    
}

} }

Main Class Run() 主类Run()

    public void run(String... args) throws Exception {
    User user1 = new User();
    user1.setFirstName("John");
    user1.setLastName("Adams");
    user1.setUsername("j");
    user1.setPassword(SecurityUtility.passwordEncoder().encode("p"));
    user1.setEmail("JAdams@gmail.com");
    Set<UserRole> userRoles = new HashSet<>();
    Role role1 = new Role();
    role1.setRoleId(1);
    role1.setName("ROLE_USER");
    userRoles.add(new UserRole(user1, role1));

    userService.createUser(user1, userRoles);
}

CascadeType.MERGE will only cascade merge events. CascadeType.MERGE将仅级联合并事件。 Persist events wont cascade so if you try to save a new user, the persist event will not cascade to User_role and no entries will be inserted into the user_role table. 持久事件不会级联,因此,如果您尝试保存新用户,则持久事件将不会级联到User_role,并且不会在user_role表中插入任何条目。

Try to add the CascadeType.PERSIST or change to CascadeType.ALL in order to cascade save the record in the database. 尝试添加CascadeType.PERSIST或更改为CascadeType.ALL以便将记录级联保存在数据库中。

@OneToMany(mappedBy = "user", cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch = FetchType.EAGER)

You can find out more about Cascade events in this answer: What do REFRESH and MERGE mean in terms of databases? 您可以在以下答案中找到有关Cascade事件的更多信息: 就数据库而言,REFRESH和MERGE是什么意思?

I was able to persist the data to the user_role associative table by implementing the JPA entity manager. 通过实现JPA实体管理器,我能够将数据持久保存到user_role关联表中。 A new EntityManager class was instantiated and the data was persisted through the javax.persistence .merge() method. 实例化了一个新的EntityManager类,并通过javax.persistence .merge()方法保留了数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM