Как использовать Spring Batch для чтения сущностей JPA с ассоциациями - PullRequest
0 голосов
/ 30 мая 2018

Мне было поручено перенести данные из "унаследованного" веб-приложения, которое использует данные JPA-источника, в более новую систему.Моими первоначальными мыслями было использование весенней партии.Я использую JpaPagingItemReader<LegacyEntity> для чтения устаревших сущностей, пользовательский ItemProcessor<LegacyEntity, NewDataDto> для преобразования сущностей и ItemWriter<NewDataDto> для отправки данных через http rest call в новую систему.

Эти сущности имеютмного один ко многим ассоциациям.LegacyEntity имеет отношение один ко многим с entityA, которое имеет отношение oneToMany с entityB.

Моя проблема заключается в том, что JpaPagingItemReader управляется jpql.Я хочу, чтобы читатель вывел один из каждого LegacyEntity со всеми загруженными ассоциациями.Я рассмотрел использование выборочного соединения в jpql, но похоже, что он не поддерживает вложенные ассоциации и испускает дубликаты.

Какой лучший способ справиться с этим?Как бы я справился с этим, если бы использовал простой старый jdbc?

Считыватели и процессоры пакетной обработки Spring все сосредоточены на обработке по одной записи за раз, только с использованием подкачки изнутри, так как я обычно читаю объекты с ассоциациями toManyв партии?

Ответы [ 2 ]

0 голосов
/ 15 июня 2018

Мне удалось решить это с помощью jdbc вместо jpa.

public class LegacyEntityReader extends JdbcPagingItemReader<LegacyEntity> {
private NamedParameterJdbcTemplate jdbcTemplate;

public LegacyEntityReader(DataSource dataSource, int pageSize) {
    //setup reader for loading legacyENtity without associations here
}

@Override
protected void doReadPage() {
    super.doReadPage();//this loads a page of root entities into a list exposed as a protected field: "results"
    List<Long> resultIds = results.stream().map(LegacyEntity::getId).collect(Collectors.toList());

    //DO queries to load associations here where legacyEntity.id in resultIds
    //Then associate in memory with the results in the results field
}
}

JPA нельзя использовать для загрузки объектов с ассоциациями в одном запросе jpa с использованием подкачки.Запрос неизбежно приведет к дублированию, и дедупликация должна произойти на всем наборе результатов в памяти, что может привести к ошибкам нехватки памяти

Это меня огорчает: (.

0 голосов
/ 04 июня 2018

Обычно вы используете шаблон запроса на вождение.Ваш ItemReader будет читать идентификаторы (или минимальную сущность).ItemProcessor затем обогатит предмет тем, что еще нужно.ItemWriter будет иметь полную сущность для записи.Подробнее об этом шаблоне можно прочитать в документации Spring Batch здесь: https://docs.spring.io/spring-batch/trunk/reference/html/patterns.html#drivingQueryBasedItemReaders

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