Search code examples
javajpaeclipselinkvaadin

Binding foreign key in Vaadin (EclipseLink)


I'm using Vaadin and EclipseLink. There are 2 tables, one is Mail, second in Customer. PK for Customer is customer_id, PK for mail is mail_id. Table Mail has Customer_id as a foreign key. How do I bind it? I tried:

binder.forField(fkCustomerId)
        .withConverter(new StringToBigDecimalConverter(FormMessages.NUMBERS_ONLY))
        .bind(Mail::getCustomerId, Mail::setCustomerId);

Then I checked the Mail-entity class and found

@JoinColumn(name = "CUSTOMER_ID", referencedColumnName = "CUSTOMER_ID")
@ManyToOne
private Customer customerId;

I checked this page - https://vaadin.com/docs/v8/framework/datamodel/datamodel-forms.html but there was nothing about fk binding.


Solution

  • Option 1: Convert customer ID

    Here I am assuming that ID field on Customer class is called id and that it is of type Long. This allows you to access that ID field through converter that produces unformatted string presentation. Note that this does not handle null value nicely.

    binder.forField(fkCustomerId)
            .withConverter(Long::valueOf, String::valueOf)
            .bind("customerId.id");
    

    Option 2: Convert customer object

    This example would take Customer object and convert that to desired format for the customer ID field. This allows you to handle null values and do more advanced formatting based on state of the whole object.

    binder.forField(fkCustomerId)
            .withConverter(new CustomerToCustomerIdConverter())
            .bind(Mail::getCustomerId, Mail::setCustomerId);
    

    You can omit convertToModelresult in the converter because you should not be creating customer objects from ID values that user types.

    public class CustomerToCustomerIdConverter implements Converter<String, Customer> {
        @Override
        public Result<Customer> convertToModel(String s, ValueContext valueContext) {
            return Result.error("not supported");
        }
    
        @Override
        public String convertToPresentation(Customer customer, ValueContext valueContext) {
            return Objects.toString(customer.getCustomerId(), "");
        }
    }
    

    TextField style

    In order to setup TextField style, you need to set it to read-only mode. And if you do not want to get the text field border at all then you need to add extra style.

    TextField fkCustomerId = new TextField();
    fkCustomerId.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS);
    fkCustomerId.setReadOnly(true);