Шаблон для доступа к данным вне транзакции - PullRequest
0 голосов
/ 26 июня 2018

У меня есть приложение Spring Boot с Spring Data JPA с hibernate и MySQL в качестве хранилища данных.

В моем приложении 3 слоя:

  1. Служба API
  2. Служба приложений
  3. Доменная служба (с репозиторием)

Роль Службы приложений заключается в преобразовании POJO с поддержкой Hibernate в DTO с учетом некоторой бизнес-логики.

POJO

SchoolClass.java

@Column
Long id;

@Column
String name;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "schoolClass")
List<Book> books;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "schoolClass")
List<Student> students;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "schoolClass")
List<Schedule> schedules;

Служба домена - Моя граница транзакции находится на уровне службы домена.

SchoolClassService.java

@Autowired
private SchoolClassRepository repository;

@Transactional(readOnly = true)
public SchoolClass getClassById(Long id) {
  return repository.findById(id);
}

Служба приложений

SchoolClassAppService.java

@Autowired
private SchoolClassService domainService;

public SchoolClassDto getClassById(Long id) {
  SchoolClass schoolClass = domainService.getClassById(id);
  // convert POJO to DTO;
  return SchoolClassDto;
}

Моя проблема заключается в том, что иногдадочерние объекты в SchoolClass пусты, когда я пытаюсь получить к ним доступ в SchoolClassAppService.Не все из них, но из трех, два будут работать нормально, но третий будет пустым.Я пытался пометить списки дочерних элементов, чтобы они могли быть с готовностью извлечены, но очевидно, что только две коллекции могут быть с нетерпением извлечены до того, как Hibernate начнет выдавать исключения, и это также не похоже на хорошую практику - всегда загружать все объекты.Я не получаю LazyInitializationException, просто список пуст.

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

Существуют ли какие-либо шаблоны, которые поддерживают границы транзакций как можно ближе к постоянному слою, в то же время делая жизнеспособной обработку данных даже после закрытия транзакции?

1 Ответ

0 голосов
/ 19 июля 2018

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

Я создал Blaze-Persistence Entity Views именно для этого варианта использования.По сути, вы определяете DTO для объектов JPA как интерфейсы и применяете их к запросу.Он поддерживает отображение вложенных DTO, коллекций и т. Д., По сути, всего, что вы ожидаете, и, кроме того, он улучшит производительность ваших запросов, поскольку будет генерировать запросы, извлекающие только те данные, которые вам действительно нужны для DTO.

Представления сущностей для вашего примера могут выглядеть следующим образом

@EntityView(SchoolClass.class)
interface SchoolClassDto {
  String getName();
  List<BookDto> getBooks();
}
@EntityView(Book.class)
interface BookDto {
  // Whatever data you need from Book
}

Запросы могут выглядеть следующим образом

List<SchoolClassDto> dtos = entityViewManager.applySetting(
  EntityViewSetting.create(SchoolClassDto.class),
  criteriaBuilderFactory.create(em, SchoolClass.class)
).getResultList();

Просто имейте в виду, что DTO должны быть не просто копиями ваших сущностей, но должныбыть разработано для вашего конкретного случая использования.

...