Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Vaadin 8 Binder
Hi,
I am trying to create a form object extending Formlayout with binder inside. So I already bound my textfields this way
// Bind fields to entity properties by naming convention
binder = new Binder<>(Item.class);
binder.forField(price)
.withConverter(new StringToBigDecimalConverter(new BigDecimal(10.00), "Price must be in ##.## format"))
.bind(Item::getPrice, Item::setPrice);
binder.forField(name).bind(Item::getName, Item::setName);
binder.forField(description).bind(Item::getDescription, Item::setDescription);
name, description and price are all textfields they are all string types except the price which is BigDecimal. I am having all this code in the form class constructor. When I am trying to initialize my binder by calling
binder.setBean(new Item()
Here is the exception:
SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [com.vaadin.server.ServiceException: java.lang.NullPointerException: value cannot be null] with root cause
java.lang.NullPointerException: value cannot be null
it throws NullPointerException. I used to bind this way in Vaadin 7 without any issues. I have another form where I don't explecitly bind my fields I do bind the by calling this on the binder object
binder.bindInstanceFields(CustomerForm.this);
This works fine for the other view where I get the exception which is the item view I need to bind manually since I have a BigDecimal field.
Thanks
This short sample works for me. What am I doing differently than you?
public class MyUI extends UI {
public class Item {
private String name;
private BigDecimal price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
@Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
TextField price = new TextField();
TextField name = new TextField();
Binder<Item> binder = new Binder<>(Item.class);
binder.forField(price)
.withConverter(new StringToBigDecimalConverter(new BigDecimal(10.00), "Price must be in ##.## format"))
.bind(Item::getPrice, Item::setPrice);
binder.forField(name).bind(Item::getName, Item::setName);
layout.addComponents(price, name);
setContent(layout);
}
@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
}
Thanks for the reply. I am using all this in a formlayout. I get a NullPointerException when I call this:
binder.setBean(new Item());
Put a breakpoint on the row and see if it's called before binder is constructed, if there is a NPE in the Item-constructor or something like that...
The problem is that the bean's values are null, and TextField in Vaadin 8 can't handle null and will fail with NPE as above mentioned. Since I believe a lot of programmers will bump into this, I have created a bug for this: https://github.com/vaadin/framework/issues/8664 The bug report also contains a workaround.
Marked as a bug. Thanks for the reporting and for the ticket
I had the same NPE issue with StringToIntegerConverter. Next line solved my problem.
binder.withConverter(Integer::valueOf, value -> (value == null) ? "" : String.valueOf(value), "Must be a number"))
In your case this should pass without NPE:
binder.forField(price)
.withConverter(value -> value.isEmpty() ? new BigDecimal("10.00") : new BigDecimal(value),
value -> value == null ? "" : value.toString(),
"Price must be in ##.## format")
.bind(Item::getPrice, Item::setPrice);
I had the same NPE issue with StringToBigDecimalConverter.
The solution of C.Berg doesn't work for me because it doesn't handle numbers in non english format.
The workaround of Martin Vyšný (https://github.com/vaadin/framework/issues/8664) is the best solution because it uses a NumberFormat with the current locale.
In your case it would look as follows:
binder.forField(price)
.withNullRepresentation("")
.withConverter(new StringToBigDecimalConverter("Price must be in ##.## format"))
.bind(Item::getPrice, Item::setPrice);
This results in an empty field, if the price is null and returns null, if the field is empty.