Spring Data JDBC: Репозиторий не сохраняет вложенные объекты, начиная с третьего уровня

#java #mariadb #spring-data-jdbc

#java #mariadb #spring-data-jdbc

Вопрос:

Я привязываюсь к сохранению древовидной сущности со структурой, подобной этой:

 CREATE TABLE `task` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `parent_id` INT(11) NULL DEFAULT NULL,
    PRIMARY KEY (`id`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

@Data
@Table
public class Task {
    @Id
    private Integer id;
    
    @MappedCollection(idColumn = "parent_id")
    private Set<Task> subItems;
}

public interface TaskRepository extends org.springframework.data.repository.CrudRepository<Task, Integer> {} 
  

Инициализировать объект:

 Task task = new Task();
Task task2= new Task();
Task task3= new Task();

task.setSubItems(Set.of(task2));
task2.setSubItems(Set.of(task3));

taskRepository.save(task);//auto-generated method
  

Spring data jdbc выполняет операцию вставки только для ‘task2’ и ‘task’. ‘task3’ игнорируется.

Java11, Spring-data-jdbc 2.0.3, Mariadb 10.3

Комментарии:

1. Не могли бы вы, пожалуйста, показать нам класс репозитория?

2. Код репозитория максимально прост: импортируйте org.springframework.data.repository. CrudRepository; общедоступный интерфейс TaskRepository расширяет CrudRepository<Задача, целое число> {}

Ответ №1:

В текущей форме это неправильное использование Spring Data JDBC, поскольку агрегаты (и корни агрегатов) не разделены должным образом.

Task похоже, что это совокупный корень, и поэтому ссылки от одного Task к его дочерним элементам должны быть через идентификатор, а не через ссылку на объект. Смотрите https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates подробнее об этом.

Поэтому я рекомендую создать для каждого Task свой собственный агрегат.

Конечно, Spring Data JDBC, вероятно, должен выдавать исключение вместо того, чтобы молча игнорировать часть модели. Пожалуйста, поднимите вопрос об этом наhttps://jira.spring.io/projects/DATAJDBC/issues