quento
quento

Reputation: 1114

Spring enum exception when a form is submitted

I have User entity and a field Role in this entity. Role is ENUM. I am trying to create user from UI. However, i am getting an exception:

org.springframework.beans.NullValueInNestedPathException: Invalid property 'role' of bean class [com.bionic.entities.User]: Could not instantiate property type [com.bionic.entities.Role] to auto-grow nested property path: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.bionic.entities.Role]: Is it an abstract class?; nested exception is java.lang.InstantiationException: com.bionic.entities.Role

Here is my Role.Enum:

package com.bionic.entities;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
@Resource
public enum Role {
ADMINISTRATOR(1, "administrator"),
TRAINER(2, "trainer"),
STUDENT(3, "student"),
RESTRICTED_ADMINISTRATOR(4, "restricted_administrator"),
RESTRICTED_TRAINER(5, "restricted_trainer");

private long id;
private String name;


Role(){}

private Role(long id, String name) {
    this.name = name;
    this.id = id;
}

public long getId() {
    return id;
}

public void setId(long id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

My User.class fields:

public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
@Column(name = "email", nullable = false, unique = true)
private String email;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "cell")
private String cell;
@Column(name="position")
private String position;

@Enumerated(EnumType.ORDINAL)
@Column(name = "role_id")
private Role role;

and, finally, my html form:

<form method="POST" action="/superAdmin/addUser" th:object="${user}">
<select name="role.id" size="2" th:field="*{role.id}" style="display: block" id="role.id"></select>
    <br /> <br /> <input type="submit" value="Upload" class="submit-but">

I've spent 2 days in order to solve that. however, it wasn't successful

How am i creating entity after:

    @RequestMapping(value = "/addUser", method = RequestMethod.POST)
public
@ResponseBody
String addUser(@ModelAttribute User user, Model model) {
    try {
        model.addAttribute("user", user);
        superAdministratorService.addUser(user);
        return "successful";
    } catch (Exception e) {
        return "You failed to upload";
    }
}

Upvotes: 0

Views: 805

Answers (1)

Francisco Hernandez
Francisco Hernandez

Reputation: 2468

Role has a default package-level constructor and a private constructor with 2 arguments, try to change your package-level constructor to public in order to do that, change

Role(){}

by

public Role(){}

I think this is the cause of your problem. But you cannot set a public constructor in enum, so maybe you must change your implementation to a final class.

UPDATE

public static Role fromId(long id) {
    if (1 == id) {
        return ADMINISTRATOR;
    }
    // TODO else if for the rest of enum instances
    } else {
        throw new AssertionError("Role not know!"); 
    }
}

A possible solution for that would be the following:

  • Use a DTO (simple POJO with the same properties that the User entity and getters and setters) to receive the object in addUser method, in that DTO define role as integer.
  • In your enum, create a method like the one above
  • Create the entity object from de DTO object, using the method above to set the role member in User entity.

Upvotes: 1

Related Questions