Spring Boot JPA, как обрабатывать обновления дочерней таблицы - PullRequest
0 голосов
/ 10 апреля 2020

Я пришел из своей предыдущей роли, заключаясь в сохранении всех данных со всеми пользовательскими SQL и JDB C. Я только что начал новую работу для малого бизнеса, где я единственный разработчик и решил разработать бизнес-системы с использованием Spring Boot с JPA для сохранения данных.

Я не знаю, как мне следует обрабатывать обновления на дочерних столах. В настоящее время я использую репозиторий Spring Crud для базовых c таблиц, но дошёл до отношений моего первого родительского потомка.

Учитывая приведенную ниже примерную структуру таблицы, как мне следует управлять обновлениями?

  +-------------------------+
  | Order                   |
  +-------------------------+
  | orderNumber      | PK   |
  +-------------------------+

  +-------------------------+
  | OrderLine               |
  +-------------------------+
  | orderNumber      | PK   |
  +-------------------------+
  | lineNumber       | PK   |
  +-------------------------+

Пользователи могут обновлять или удалять существующие строки заказа.

При обновлении я мог сначала удалить все существующие строки заказа и воссоздать их, но не уверен, что это плохая практика?

Каков нормальный подход с Spring Boot и JPA?

Должен ли я использовать какие-то каскадные настройки для родительского объекта?

Ответы [ 3 ]

0 голосов
/ 10 апреля 2020

Вы можете выполнить следующее сопоставление в Spring Data JPA для своих организаций, чтобы повторить вышеуказанное требование. Вы пытаетесь создать композиционные отношения между Order и OrderLine, где прежний является владельцем, а не родительскими / дочерними отношениями.

@Entity
@Table(name="Order")
class Order {
    @Id
    private Long orderNumber;

    @OneToMany(mappedBy="order")
    private List<OrderLine> orderLines;

}

@Entity
@Table(name="OrderLine")
class OrderLine {
    @ManyToOne
    @JoinColumn(name="orderNumber", nullable=false)
    private Order order;

    private Long lineNumber;

}
0 голосов
/ 10 апреля 2020

При обновлении я мог бы сначала удалить все существующие строки заказа и воссоздать их, но не уверен, что это плохая практика?

обновление только тех строк заказа, которые нуждаются в обновлении, Лучшая практика.

Я мог бы сначала удалить все существующие строки заказа и воссоздать их

Это может привести к выполнению большого количества запросов на удаление и большого количества запросов на вставку, которые плохо. Автоматически сгенерированные id строк ордеров также быстро увеличатся, а это не то, что вам нужно.

Какой нормальный подход у Spring Boot и JPA? Должен ли я использовать какие-то каскадные настройки на родительском объекте?

Да, вам следует. Вот пример:

Order. java

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long orderNumber;

    @Version
    private Long version = 0L;

    @OneToMany(mappedBy="order", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<OrderLine> orderLines;

    // equals() and hashcode() implementation
    // getter() and setter() implementation
}

OrderLine. java

@Entity
public class OrderLine {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long lineNumber;

    @ManyToOne
    @JoinColumn(name="order_id", nullable=false)
    private Order order;

    @Version
    private Long version = 0L;

    // equals() and hashcode() implementation
    // getter() and setter() implementation
}

И, наконец, пример обновления:

public boolean update(Order order, long orderLineId, OrderLine updatedOrderLine) {
    if(order == null || updatedOrderLine == null)
        return false;

    if(order.getOrderLines() == null)
        return false;

    Optional<OrderLine> optTargetOrderLine = order.getOrderLines().stream()
.filter(orderline -> orderLine.getLineNumber() == orderLineId).findFirst();

    if(!optTargetOrderLine.isPresent())
        return false;

    OrderLine targetOrderLine = optTargetOrderLine.get();

    // now implement the update function
    boolean status = update(targetOrderLine, updatedOrderLine);

    // if status is true, you also have to call save() on your OrderRepository
    return status;
}
0 голосов
/ 10 апреля 2020

Не могли бы вы заменить orderNumber на orderId? Ссылка таблицы orderLine на таблицу Order через внешний ключ orderId имеет большее значение для вашего кода. Если вы можете, используя столбец соединения и каскадную конфигурацию, вместо удаления всех orderLine и их повторного создания, пусть JPA сделает это за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...