Search code examples
javaspringspring-bootabstract-classrequest-mapping

pass abstract parameter to requestMapping function with spring boot


I have an abstract class "Agent" and 3 other subclasses "Developer", "Support" and "Admin"

Here is the code source of "Agent" :

@Entity
@Table(name = "agents")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "role", discriminatorType = 
DiscriminatorType.STRING, length = 3)

public abstract class Agent implements Serializable {

@Id
@GeneratedValue
private int id;

private String name;

private String lastName;

.........}

The code source of "Developer" classe

@Entity
@DiscriminatorValue("dev")

public class Developer extends Agent {

/*------------------- constructors -------------------*/
public Developer() {
    super();
}


public Developer(String name, String lastName, ....) {

    super(name, lastName, ...);

}

}

The rest of the classes "Admin", "Supprort" has the same form.

Here is my controller code Admin controller :

@Controller

public class AdminController {


/*------- attributs -------*/


@Autowired
@Resource(name = "admin")
private IAdmin iAdmin;


@Autowired
private AgentValidator agentValidator;

........

@RequestMapping(value = "/admin/save/developer", method = RequestMethod.POST)

public String createAgentAccount(Model model, String admin_id, String confirmPassword, String action, @ModelAttribute("agent") Developer developer, BindingResult result) {

    Agent admin = iAdmin.profile(Integer.parseInt(admin_id));

    developer.setConfirmPassword(confirmPassword);

    agentValidator.validate(developer, result);

    if (result.hasErrors()) {

        model.addAttribute("action", action);

        return "formAgents";

    }

    if (action.equals("create")) {

        iAdmin.createAgent(admin, developer);

    } else {

        iAdmin.updateAgent(admin, developer);

    }

    return "redirect:/admin/show/agents";

}

.......

As you see this function create and update the developer account, But i need to save all agents types [admin, developer, support], I try this :

   public String createAgentAccount(Model model, ... , @ModelAttribute("agent") Agent developer, BindingResult result) {.....}

But i get this error :

Tue Aug 22 19:54:03 WEST 2017
There was an unexpected error (type=Internal Server Error, status=500).
Failed to instantiate [com.GemCrmTickets.entities.Agent]: Is it an    abstract class?; nested exception is java.lang.InstantiationException

I know that is impossible to instanciate an abstract Class. I don't want to do a function for each type of agent, One for all will be the best solution. So i need your help please. And thank you.


Solution

  • Your answer is one word. Use Ad hoc polymorphism, which means you can have multiple methods of createAgentAccount, then in each of them call an other method to handle the details.

    UPDATE This is what I think you want

    @RequestMapping(value = "/admin/save/developer", method = RequestMethod.POST)
    public String createAgentAccount(Model model, String admin_id, String confirmPassword, String action, @ModelAttribute("agent") Developer developer, BindingResult result) {
        return createAgentAccount(model, admin_id, confirmPassword, action, developer, result);
    }
    
    @RequestMapping(value = "/admin/save/support", method = RequestMethod.POST)
    public String createAgentAccount(Model model, String admin_id, String confirmPassword, String action, @ModelAttribute("agent") Support support, BindingResult result) {
        return createAgentAccount(model, admin_id, confirmPassword, action, support, result);
    }
    
    private String createAccount(Model model, String admin_id, String confirmPassword, String action, Agent agent, BindingResult result) {
    
        Agent admin = iAdmin.profile(Integer.parseInt(admin_id));
    
        agent.setConfirmPassword(confirmPassword);
    
        agentValidator.validate(agent, result);
    
        if (result.hasErrors()) {
    
            model.addAttribute("action", action);
    
            return "formAgents";
        }
    
        if (action.equals("create")) {
    
            iAdmin.createAgent(admin, agent);
    
        } else {
    
            iAdmin.updateAgent(admin, agent);
    
        }
    
        return "redirect:/admin/show/agents";
    }