Thymeleaf registration page - Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringInputGeneralFieldAttrProcessor'
Asked Answered
S

2

8

I'm making a registration page for a website. I understand that in order for a new User to be created, an id is required, so we have the field:

<input type="hidden" th:field="{*id} />

However, when I go to the page, I get the error I mentioned in this post's title.

Here is the form in question:

<form th:action="@{/users/register}" th:object="${user}" class="form-signin" method="POST">
    <h2 class="form-signin-heading">Register</h2>
    <input type="hidden" th:field="*{id}" />
    <label for="inputUsername" class="sr-only">Username*</label>
    <input type="text" th:field="*{username}" name="username" id="inputUsername" class="form-control" placeholder="Username" required="required" autofocus="autofocus" />
    <label for="inputEmail" class="sr-only">Email Address*</label>
    <input type="text" th:field="*{email}" name="email" id="inputEmail" class="form-control" placeholder="Email address" required="required" autofocus="autofocus" />
    <label for="inputPassword" class="sr-only">Password</label>
    <input type="password" th:field="*{password}" name="password" id="inputPassword" class="form-control" placeholder="Password" required="required" />
    <label for="inputConfirmPassword" class="sr-only">Confirm Password</label>
    <input type="password" th:field="${confirmPassword}" name="confirmPassword" id="inputConfirmPassword" class="form-control" placeholder="Confirm password" required="required" />
    <button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
</form>

Here is my UserController:

@RequestMapping("/register")
public String registerAction(Model model) {
    model.addAttribute("user", new User());
    model.addAttribute("confirmPassword", "");
    return "views/users/register";
}

@RequestMapping(value="/register", method = RequestMethod.POST)
public String doRegister(User user) {
    User savedUser = userService.save(user);
    return "redirect:/"; //redirect to homepage
}

And the first part of the User entity:

@Entity
@Table(name = "users")
public class User {

// Default constructor require by JPA
public User() {}

@Column(name = "id")
@Id @GeneratedValue
private Long id;

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

public long getId() {
    return id;
}

From what I can see, there's nothing wrong here so I'm stuck.

I'm following this example: https://github.com/cfaddict/spring-boot-intro

Any ideas?

Schooner answered 17/3, 2016 at 21:47 Comment(0)
L
3

The problem is the way you have declared your id property. The field uses a reference type Long which is null. The getter uses a primitive long. When Spring accesses the id field it tries to unbox a null value causing an error. Change your domain class to be

@Entity
@Table(name = "users")
public class User {

    // Default constructor required by JPA
    public User() {}

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Long id;

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

    public Long getId() {
        return id;
    }
}
Lactation answered 18/3, 2016 at 9:10 Comment(0)
V
3

I don't know if you have a class like this

@Controller
@RequestMapping("/users")
public class MyController{

    @RequestMapping("/register")
    public String registerAction(Model model) {
        model.addAttribute("user", new User());
        model.addAttribute("confirmPassword", "");
        return "views/users/register";
    }

    @RequestMapping(value="/register", method = RequestMethod.POST)
    public String doRegister(User user) {
        User savedUser = userService.save(user);
        return "redirect:/"; //redirect to homepage
    }
}

becouse if you don't have the @RequestMapping("/users") this is a problem becous if you dont have this annotation in you class the correct actione in the thymeleaf templace should be "@{/register}" other wise yon don't have the endpoint pubblished in other words with the methods that you posted you should have a template like this:

<form th:action="@{/register}" th:object="${user}" class="form-signin" method="POST">
    <h2 class="form-signin-heading">Register</h2>
    <input type="hidden" th:field="*{id}" />
    .... should be as you written
    <input type="password" th:field="*{confirmPassword}" id="inputConfirmPassword" class="form-control" placeholder="Confirm password" required="required" />
    <button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
</form>

reading beter the your html you probably should have th:field="*{confirmPassword}" and not th:field="${confirmPassword}". another think that in my opinion don't works is that you repeate name attribute. The my advice is don't repeate and let to thymeleaf the work of build the correct attribute for databinding.

Vicariate answered 17/3, 2016 at 22:29 Comment(3)
I've just tried that change but it didn't make a difference - I'm sure it's something to do with the id field, as taking out the hidden field allows the registration form to be viewed at least.Schooner
I can suggest to see this guide spring.io/guides/gs/handling-form-submissionVicariate
I use thymeleaf in a opensource proects github.com/mrFlick72/socialDocumentLibrary/blob/master/…. in this link you can see how I done a thing like you, for file uploadVicariate
L
3

The problem is the way you have declared your id property. The field uses a reference type Long which is null. The getter uses a primitive long. When Spring accesses the id field it tries to unbox a null value causing an error. Change your domain class to be

@Entity
@Table(name = "users")
public class User {

    // Default constructor required by JPA
    public User() {}

    @Id
    @Column(name = "id")
    @GeneratedValue
    private Long id;

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

    public Long getId() {
        return id;
    }
}
Lactation answered 18/3, 2016 at 9:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.