Привязка внешнего ключа в Vaadin (EclipseLink)

Я использую Vaadin и EclipseLink. Есть 2 таблицы, одна - Почта, вторая - Клиент. PK для клиента - это customer_id, PK для почты - mail_id. Table Mail имеет Customer_id в качестве внешнего ключа. Как его привязать? Я пытался:

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

Затем я проверил класс Mail-entity и обнаружил

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

Я проверил эту страницу - https://vaadin.com/docs/v8/framework/datamodel/datamodel-forms.html, но о привязке fk ничего не было.


person revolt    schedule 06.10.2017    source источник
comment
Было бы хорошо добавить дополнительную информацию о том, чем вы хотите заниматься. Вероятно, вы не хотите позволять пользователю напрямую редактировать ваш первичный ключ. Вероятно, его следует установить на основе чего-то другого, кроме ввода пользователя.   -  person Mika    schedule 08.10.2017
comment
Table Mail содержит некоторые настройки почты для клиентов для другого приложения и содержит customer_id в качестве внешнего ключа. EclipseLink сопоставил его с идентификатором клиента customerId, но я не могу привязать объект класса Customer, нужно ли мне его во что-то преобразовать?   -  person revolt    schedule 09.10.2017
comment
Что вы хотите сделать с объектом клиента? Вы хотите отобразить значение customer_id в ярлыке, показать раскрывающийся список для создания нового соединения или что-то еще?   -  person Mika    schedule 09.10.2017
comment
О да, я хочу показать значение на этикетке.   -  person revolt    schedule 09.10.2017
comment
Я думал, что это будет очень просто: binder.forField (fkCustomerId) .bind (Mail :: getCustomerId, Mail :: setCustomerId); но нет, это так не работает   -  person revolt    schedule 09.10.2017


Ответы (1)


Вариант 1. Преобразование идентификатора клиента

Здесь я предполагаю, что поле ID в классе Customer называется id и имеет тип Long. Это позволяет вам получить доступ к этому полю идентификатора через конвертер, который производит неформатированное строковое представление. Обратите внимание, что это не обрабатывает значение null должным образом.

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

Вариант 2. Преобразование объекта клиента

В этом примере объект Customer будет преобразован в желаемый формат для поля идентификатора клиента. Это позволяет обрабатывать null значений и выполнять более сложное форматирование в зависимости от состояния всего объекта.

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

Вы можете опустить convertToModelresult в преобразователе, потому что вам не следует создавать объекты клиентов из значений идентификаторов, вводимых пользователем.

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, вам необходимо установить его в режим только для чтения. А если вы вообще не хотите получать границу текстового поля, вам нужно добавить дополнительный стиль.

TextField fkCustomerId = new TextField();
fkCustomerId.addStyleName(ValoTheme.TEXTFIELD_BORDERLESS);
fkCustomerId.setReadOnly(true);
person Mika    schedule 09.10.2017