Представление наследования одной таблицы и прикладное решение для Spring Boot и Thymeleaf

Я решил использовать наследование одной таблицы, что приводит к созданию нескольких классов и я не могу получить доступ к дочерним полям через родительский объект в части представления приложения. Пока я не нашел хорошего решения, как с этим справиться в Thymeleaf. Что это значит?
До того, как я разделил свои классы для использования наследования одной таблицы, я мог легко передать 1 объектный класс, содержащий всю информацию, необходимую для создания или отображения объекта, но в нем было слишком много полей, которые были бы нулевыми. С несколькими классами тимелеаф на самом деле не позволяет вам приводить объекты к другому типу (и, насколько я понимаю, было бы не рекомендуется делать это в части просмотра приложения). Итак, каков на самом деле лучший способ справиться с этой проблемой? Я могу придумать такие идеи, как:

  1. Создайте DTO, который содержит поля из всех классов и преобразуйте объекты в этот класс, было бы здорово в режиме создания (POSTing DTO, а затем создание объекта из него и добавление в базу данных). Но если бы я использовал этот метод для отображения информации, это означало бы приведение каждого из объектов к классу DTO, что, на мой взгляд, упускает момент наследования одной таблицы. Я чувствую, что это слишком похоже на возвращение к полному отсутствию наследства.
  2. Передача нескольких объектов или родительского объекта + другого объекта, который будет содержать остальную информацию, которой нет в родительском классе. Это тоже выглядит как-то странно.
  3. Добавление одного метода в родительский класс для каждого дополнительного поля подкласса и перезапись их в подклассах, чтобы возвращать фактические значения, в то время как родительский возвращал бы значение null. Не уверен, что это решит проблему создания объектов из представления.

Давайте представим этот пример с тремя простыми классами, где Person является родительским классом, а Client и Employee являются его дочерними элементами. Я пропущу геттеры, сеттеры и конструкторы для простоты.

Основной класс Person, содержащий общие поля

@Entity
@Inheritance
@DiscriminatorColumn(name = "person_type", discriminatorType = DiscriminatorType.STRING)
public abstract class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
int personId;
int age;
String name;
}  

Класс Client, расширяющий person дополнительным полем favouriteProduct

@Entity
@DiscriminatorValue(value= "CLIENT")
public class Client extends Person {

String favouriteProduct;
}

Класс Employer, расширяющий person дополнительными полями оклада и должности.

@Entity
@DiscriminatorValue(value= "EMPLOYEE")
public class Employee extends Person {

String position;
int salary;
}

Учитывая эту простую структуру, я хотел бы создать объекты Employee и Client через одну форму с помощью запроса POST, а также отобразить их вместе в другом представлении с их полями, уникальными для каждого подкласса. Проблема в том, что мне нужно передать объект, который содержит все поля, в представление, чтобы заставить его работать, что возвращает к проблеме и решениям, которые я придумал. Есть ли правильный способ или лучшая практика, как справиться с этим? Я думал, что DTO должны скорее уменьшаться от полных объектов до объектов с меньшим количеством полей.

Вывод: если ответ на самом деле не так прост, то в чем на самом деле польза от наследования одной таблицы в этом случае и почему не стоит просто вернуться к реализации с одной таблицей? Я уже знаю о полиморфных запросах, и это приятный бонус, но пока я не могу разобраться с проблемой, описанной выше. Заранее спасибо!


person Densau    schedule 25.09.2020    source источник
comment
Моя проблема может быть похожа на эту, но на самом деле она не получила хорошего ответа: stackoverflow.com/questions/41861237/   -  person Densau    schedule 25.09.2020


Ответы (1)


Я не знаю о Thymeleaf (извините!), но я немного знаю об объектно-ориентированном программировании. Если оставить в стороне фреймворки и говорить с чисто объектно-ориентированной точки зрения, родительские классы ничего не знают о своих потомках (наследниках). Только обратное может быть правдой, и это если вы используете соответствующие модификаторы доступа. Учитывая сказанное, я считаю, что вы не можете делать то, что хотите, если под капотом не будет какой-то уродливой черной магии, ха-ха.

person Caio Dornelles Antunes    schedule 25.09.2020
comment
Я чувствую, что конечный результат для базы данных почти такой же, за исключением того, что на стороне приложения у меня есть 1 класс вместо 3, и этот класс представляет больше, чем должен, что немного утомительно. Но я не уверен, стоит ли идти по этому пути и реализовывать наследование одной таблицы, поскольку это сделает передачу и преобразование всех объектов действительно подверженными ошибкам. Может быть, у кого-то со специфическими знаниями о весенней загрузке и тимелеафе есть какие-то хитрости. - person Densau; 25.09.2020