0

I'm trying to implement a create/edit user for my application.

On my controller, I have the following methods to create a new or to edit an existing user.

@RequestMapping(value = "/admin/createUser", method = RequestMethod.GET)
public void createtUser(ModelMap model) throws IOException, Exception {
    model.addAttribute("pojo", new UserPojo());
    model.addAttribute("roles", initializeProfiles());
}

@ModelAttribute("roles")
public List<UserProfile> initializeProfiles() {
    return userProfileService.findAll();
}

@RequestMapping(value = "/admin/createUser", method = RequestMethod.POST)
public String createUserPost(ModelMap model, @Valid @ModelAttribute("pojo") UserPojo pojo, BindingResult result, Errors errors) {

    if (errors.hasErrors()) {
        System.out.println("There are errors");
        return "/admin/createUser";
    }

    System.out.println(pojo.getProfiles());

    try {
        userService.save(pojo.getSsoId(),
                         pojo.getFirstName(),
                         pojo.getLastName(),
                         pojo.getEmail(),
                         pojo.getProfiles(),
                         pojo.getPassword());
    } catch (IOException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }

    model.addAttribute("success", "User " + pojo.getSsoId() + " has been created successfully");

    return "redirect:/admin/homeAdmin";
}

The UserPojo model is:

public class UserPojo {

    private String id;

    private String ssoId;

    private String firstName;

    private String lastName;

    private String email;

    private String password;

    private String state;

    private Set<UserProfile> profiles;

    // getters and setters

The UserProfile pojo is:

@Entity
@Table(name="userProfile")
public class UserProfile extends BasePojo {

    @Column(name="type", length=15, unique=true, nullable=false)
    private String type = UserProfileType.USER.getUserProfileType();

    // getter and setter

And the UserProfileType enum is:

public enum UserProfileType {

    USER("USER"),
    DBA("DBA"),
    ADMIN("ADMIN");

    String type;

    private UserProfileType(String userProfileType) {
        this.type = userProfileType;
    }

    public String getUserProfileType() {
        return type;
    }

On my createUser.html page, I select users with:

<select class="form-control" th:field="*{profiles}" name="profiles" multiple="multiple">
    <option th:each="role : ${roles}"
        th:value="${{profiles}}"
        th:text="${role.type}">
    </option>
</select>

Problem is that when I submit data, the controller sees null on the UserPojo profiles field and does not persist the assigned user profiles.

How to work this out?

gtludwig
  • 5,411
  • 10
  • 64
  • 90
  • Is this a form submission to create user, if yes, then try adding **name** attribute to every form fields and that name should match the variables defined in your pojo. – Akhil Jun 09 '16 at 08:20

1 Answers1

1

First, I think you need to change mapping here :

@Entity
@Table(name="userProfile")
public class UserProfile extends BasePojo {

@Enumerated(EnumType.STRING)
@Column(name="type", length=15, unique=true, nullable=false)
private UserProfileType type = UserProfileType.USER;

// getter and setter

When, I guess there are the error on <options> :

th:value="${{profiles}}"

If roles is a values from the enum maybe you try :

<option th:each="role : ${roles}"
    th:value="${role.type.name()}" // or role.type (If you don't want to change mapping)
    th:text="${role.type}">
</option>

For getting enum value by name :

public enum UserProfileType {

USER("USER"),
DBA("DBA"),
ADMIN("ADMIN");

String type;

private UserProfileType(String userProfileType) {
    this.type = userProfileType;
}

public String getUserProfileType() {
    return type;
}

public UserProfileType getByName(String name) {
    return UserProfileType.valueOf(name);
}

Also you need the formatter for type UserProfileType:

public class UserProfileTypeFormatter implements Formatter<UserProfileType> {

public UserProfileTypeFormatter() {
    super();
}

@Override
public String print(UserProfileType object, Locale locale) {
    return object.getType();
}

@Override
public UserProfileType parse(String text, Locale locale) throws ParseException {
    return UserProfileType.getByName(text);
}

}
sanluck
  • 1,544
  • 1
  • 12
  • 22
  • Thanks, @sanluck, I'm attempting to implement as per your suggestion. The `UserProfileTypeFormatter` imports `org.springframework.format.Formatter`, right? I fail to see where it is referenced. – gtludwig Jun 09 '16 at 14:21
  • 1
    Yes, you right `o.s.f.Formatter`. You can refer to [this answer](http://stackoverflow.com/questions/36368190/can-i-autowired-one-repository-inside-spring-boot-custom-validator/36369269#36369269) – sanluck Jun 10 '16 at 02:57