Подтвердить что ты не робот

Использование свойств javafx.beans в классах моделей

Правильно ли использовать классы JavaFX beans в классах моделей?

Интересно, хорошо ли использовать свойства в классах моделей, чтобы они могли легче связывать их с компонентами представления. Я не беспокоюсь о доступности этих библиотек в будущем, потому что моя программа будет запущена на JRE8 или более поздней, но характер использования библиотек JavaFX в классах моделей делает меня скептическим, и я беспокоюсь о текущей и будущей неспособности специально, потому что Я хочу использовать Hibernate для сохранения этих атрибутов.

Примечание. Я использую чистую среду JavaFX, и мне никогда не понадобится компиляция Swing в моем приложении.

4b9b3361

Ответ 1

Я собираюсь предложить здесь своеобразное мнение.

Свойства JavaFX и JPA

Как я прокомментировал ответ jewelsea, использование JavaFX на основе свойств bean с JPA возможно, если вы используете "доступ к свойствам", а не "доступ к полю". сообщение в блоге. Я связал здесь более подробно об этом, но основная идея заключается в том, что любые аннотации должны быть в методах get...(), а не на полях. Насколько я вижу, это предотвращает использование каких-либо свойств свойств JavaFX только для чтения в сочетании с JPA, но я никогда не чувствовал, что JPA хорошо играет с свойствами только для чтения (т.е. Получать методы и не устанавливать метод) в любом случае.

Сериализация

В отличие от моего комментария на jewelsea answer и с помощью нескольких недель для работы с этим (и будучи помещенным в положение, когда мне пришлось реплицировать несколько классов сущностей на стороне клиента JavaFX с использованием свойств JavaFX), я что отсутствие сериализации свойств JavaFX можно обойти. Главное наблюдение заключается в том, что вам действительно нужно только сериализовать обернутое состояние свойства (не, например, любых слушателей). Вы можете сделать это, выполнив java.io.Externalizable. Externalizable - это суб-интерфейс Serializable, который требует, чтобы вы заполнили методы readExternal(...) и writeExternal(...). Эти методы могут быть реализованы для экстернализации только состояния, завершенного свойством, а не самого свойства. Это означает, что если ваша сущность сериализована и затем десериализована, вы получите новый экземпляр свойства, и никакие слушатели не будут сохранены (т.е. слушатели фактически станут transient), но насколько я вижу, это будет что было необходимо в любом разумном случае.

Я экспериментировал с beans таким образом, и все это, похоже, работает хорошо. Кроме того, я провел небольшой эксперимент по передаче их между клиентом и успокоительной веб-службой, используя картографию Jackson для преобразования в представление JSON и из него. Поскольку mapper просто полагается на использование методов get и set, это работает отлично.

Некоторые оговорки

Необходимо соблюдать пару моментов. Как и в случае любой сериализации, важно иметь конструктор без аргументов. И, конечно же, все значения, обернутые свойствами JavaFX, сами должны быть сериализуемыми - опять же это то же правило, что и для любого сериализуемого bean.

Точка о свойствах JavaFX, работающая с помощью побочных эффектов, хорошо взламывается, и необходимо проявлять осторожность при перемещении этих свойств (которые в некоторой степени разработаны с учетом одной многопоточной модели) многопоточный сервер. Хорошее эмпирическое правило, вероятно, заключается в том, что если вы используете эту стратегию, слушатели должны регистрироваться только на стороне клиента (и помните, что эти слушатели преходящи в отношении передачи обратно на сервер, будь то путем сериализации или представления JSON). Конечно, это предполагает, что использование этих на стороне сервера может быть плохой дизайн; это становится компромиссом между удобством наличия единого объекта, который является "всем для всех людей" (наблюдаемые свойства для клиента JavaFX, сериализуемые для сохранения и/или удаленного доступа и с постоянными сопоставлениями для JPA) по сравнению с возможностью раскрытия (например, наблюдаемость), где это может быть не совсем правильно (на сервере).

Наконец, если вы используете аннотации JPA, у них есть сохранение во время выполнения, что подразумевает (я думаю), что вашему клиенту JavaFX потребуется спецификация javax.persistence для пути к классам.)

Вот пример такого существа "человек для всех сезонов":

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.time.MonthDay;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 * Entity implementation class for Entity: Person
 *
 */
@Entity

public class Person implements Externalizable {


    private static final long serialVersionUID = 1L;

    public Person() {

    }

    public Person(String name, MonthDay birthday) {
        setName(name);
        setBirthday(birthday);
    }

    private final IntegerProperty id = new SimpleIntegerProperty(this, "id");

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    public int getId() {
        return id.get();
    }

    public void setId(int id) {
        this.id.set(id);
    }

    public IntegerProperty idProperty() {
        return id ;
    }

    private final StringProperty name = new SimpleStringProperty(this, "name");

    // redundant, but here to indicate that annotations must be on the property accessors:
    @Column(name="name")
    public final String getName() {
        return name.get();
    }

    public final void setName(String name) {
        this.name.set(name);
    }

    public StringProperty nameProperty() {
        return name ;
    }

    private final ObjectProperty<MonthDay> birthday = new SimpleObjectProperty<>();

    public final MonthDay getBirthday() {
        return birthday.get();
    }

    public final void setBirthday(MonthDay birthday) {
        this.birthday.set(birthday);
    }

    public ObjectProperty<MonthDay> birthdayProperty() {
        return birthday ;
    }

    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeInt(getId());
        out.writeObject(getName());
        out.writeObject(getBirthday());
    }

    @Override
    public void readExternal(ObjectInput in) throws IOException,
            ClassNotFoundException {
        setId(in.readInt());
        setName((String) in.readObject());
        setBirthday((MonthDay) in.readObject());
    }

}

Ответ 2

Дизайн свойств JavaFX

Свойства JavaFX разработаны таким образом, что вам не нужно запускать программу JavaFX для их использования. Разделы Oracle с использованием свойств JavaFX и связанного с ним учебника демонстрируют такое использование (например, класс Bill для моделирования свойств счета). В примере из учебника запускается стандартная Java-программа с main, а не JavaFX Application. Таким образом, вы можете в общих чертах использовать свойства и привязки без дополнительных требований к среде исполнения JavaFX. Это означает, что вы можете, например, использовать свойства и привязки JavaFX в приложении на стороне сервера.

"Правильные" практики

Хорошо, так что вы можете это сделать, но это "правильная" практика?

Я не думаю, что многие люди используют свойства JavaFX таким образом. Одна из причин этого - просто потому, что свойства JavaFX довольно новы. Я не думаю, что "неправильно" использовать свойства JavaFX в объектах модели.

Предостережение

Свойства JavaFX не поддерживают сериализацию Java (под этим я подразумеваю прямую поддержку интерфейса Serializable). Многим технологиям Java на стороне сервера может потребоваться сериализация модели, и они не смогут сериализовать любой объект, который использует свойства JavaFX.

Сами свойства JavaFX не осведомлены о контейнерах и работают через побочные эффекты (например, изменение свойства может инициировать обновление для другого связанного значения), поэтому имейте это в виду и убедитесь, что этот вид обработки является приемлемым подходом в вашем Окружающая среда. В частности, будьте осторожны, чтобы вы не генерировали нежелательные условия гонки в многопоточной серверной среде (клиентские приложения JavaFX обычно требуют меньше внимания, поскольку JavaFX обычно работает в основном как однопоточная среда).

Свойства JavaFX и Hibernate/JPA

Я не думаю, что смешение свойств JavaFX в классах сущностей Hibernate (или JPA) - хорошая идея. Я не видел, чтобы кто-то это делал. Сам Hibernate не знает свойств JavaFX и в целом предназначен для работы с Java-примитивами, такими как Strings и ints, поэтому я не знаю, как он может автоматически сопоставить свойство JavaFX с полем базы данных.

Вероятно, вам понадобится настройка, которая определила бы иерархию классов объектов и параллельную иерархию для ваших классов классов на основе свойств JavaFX и, наконец, слой сопоставления, который сопоставлен между ними. Такая архитектура является, по существу,

Ответ 3

для сохраняющихся коллекций jpa просто используйте эту подпись для метода getter.

@OneToMany
List<Person> getAll()
{
return observableList;
}