Noorus Khan
Noorus Khan

Reputation: 1476

ManyToMany relation : Data not persisting in DB

After getting values from UI, then able to extract the values from DTO and assign to respective fields. After creating a complete user object, when tried to persist this user object in db, the values are not getting persisted in the database.

Not able to catch where getting wrong, Could some one please help me. Thanks.

ControllerFile.java

public String createNewUser(Model model,@ModelAttribute("UserRoleDTO") UserRoleDTO userRoleDTO) {
        String message = null;
        User user = null;
        List<Role> roles = new ArrayList<Role>();
            user = userRoleDTO.getUser();
            for(Long r:userRoleDTO.getRole()) {
                Role role = new Role();
                role.setRoleId(r);
                roles.add(role);    
            }
            user.setRoles(roles);
            loginService.createUser(user);
}

DaoImplFile.java

@Repository
@Transactional
public class DaoImplFile implements LoginDao {

    private EntityManager entityManager;

    public EntityManager getEntityManager() {
        return entityManager;
    }

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public String createNewUser(User user) {
        String message = null;
        try{
            entityManager.persist(user);
            message = "User info has been submitted successfully";
        }catch(Exception e){
            message = "Sorry !!!! User info has not been submitted successfully";
        }
        return message;
    }
}

User.java

@Entity
@Table(name="user")
public class User implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="userId")
    private Long userId;

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "userrole",joinColumns = { 
            @JoinColumn(name = "UserId", nullable = false, updatable = false) }, 
            inverseJoinColumns = { @JoinColumn(name = "roleId", 
                    nullable = false, updatable = false) })
    private Set<Role> roles;

    }

Role.java

@Entity
@Table(name="role")
public class Role {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name="roleId")
    private Long roleId;

    @ManyToMany(mappedBy = "roles")
    private Set<User> user;
}   

Upvotes: 0

Views: 75

Answers (2)

Noorus Khan
Noorus Khan

Reputation: 1476

I have changed in USER class, and that worked for me...

CascadeType.ALL to CascadeType.MERGE

thanks @mh-dev, explained the way to counter the same problem, i have not tried though, feel that should also work.

Upvotes: 0

mh-dev
mh-dev

Reputation: 5503

There is a bi-directional relation between User and Role, but you only set one direction. This can lead to unexpected behaviour.

Change createNewUser to:

public String createNewUser(Model model,@ModelAttribute("UserRoleDTO") UserRoleDTO userRoleDTO) {
    String message = null;
    User user = null;
    List<Role> roles = new ArrayList<Role>();
        user = userRoleDTO.getUser();
        for(Long r:userRoleDTO.getRole()) {
            Role role = new Role();
            role.setRoleId(r);
            List<User> users = new ArrayList<>();
            users.add(user);
            role.setUser(users);
            roles.add(role);    
        }
        user.setRoles(roles);
        loginService.createUser(user);
}

It might be necessary to save the user before adding the roles, but I am not fully sure about that.

Upvotes: 2

Related Questions