Spring data jdbc: one-to-one, one-to-many relations

Spring data jdbc: one-to-one, one-to-many relations

Т.к. в Spring Data JDBC нет стандартных хибернейтовских аннотаций типа @OneToOne, @OneToMany и @JoinColumn, то для меня было проблематично понять можно ли там вообще организовать отношения и использовать их при получении или сохранении объектов. Оказалось это делается так:

One-To-One

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Operation {
    @Id
    private Long id;

    //idColumn - The column name for id column in the corresponding relationship table.
    @MappedCollection(idColumn = "operation_id")
    private TaxInfo taxInfo;
}
-------------------------------------------------------------
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TaxInfo {
    @Id
    private Long id;
    private Long operationId;
    private Integer amount;
}

При такой реализации объект Operation без проблем вычитывается из БД уже с смапленным внутрь TaxInfo. Так же без проблем работает сохранение нового Operation с заполненным TaxInfo (корректно заполняются поля id и operationId.

One-To-Many

Несколько проблематично отношение один ко многим. Здесь сложность состояла в том, что я использовал List для агрегации нескольких TaxInfo, и при сохранении получал эксепшн ConstraintViolationException.

Решение состояло в том, чтобы использовать Set (или Map):

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Operation {
    @Id
    private Long id;

    //idColumn - The column name for id column in the corresponding relationship table.
    @Builder.Default
    @MappedCollection(idColumn = "operation_id")
    private Set<TaxInfo> taxInfo = new HashSet<>();
}
-------------------------------------------------------------
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class TaxInfo {
    @Id
    private Long id;
    private Long operationId;
    private Integer amount;
}

При такой реализации объект Operation без проблем вычитывается из БД уже с смапленными внутрь TaxInfo. Так же без проблем работает сохранение нового Operation с заполненными TaxInfo (корректно заполняются поля id и operationId.


Теперь про эксепшены. У меня были проблемы именно с аннотацией @MappedCollection в совокупности с использованием List:

  • использование @MappedCollection(idColumn = «operation_id»)
    Эксепшн ConstraintViolationException (Столбец «OPERATION_KEY» не найден). Проблема в том, что нужно указать keyColumn (или использовать суффикс «_KEY»). keyColumn — The column name for key columns of List or Map collections in the corresponding relationship table. Т.е. как я понял, приложение желает заполнить id для List или key для Map. И если с Map всё вроде ясно, то заполнение id для List — странная затея, и мне так и не удалось понять как оно работает (поятоянно получал эксепшн при сохранении)
  • использование @MappedCollection(idColumn = «operation_id», keyColumn = «operation_id») или @MappedCollection(idColumn = «operation_id», keyColumn = «id»)
    Эксепшн ConstraintViolationException Нарушение ссылочной целостности. Второй вариант ( keyColumn = «id» ) может показаться рабочим, но только при сохранении первой записи. Тоже не понятно как это использовать с List
(Просмотрено 1 415 раз, 1 раз за сегодня)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *