Предположим, что у меня есть следующие объекты:
Код: Выделить всё
class A {
@Id
@Column(name = "id", nullable = false)
private UUID id;
@OneToMany(mappedBy = "a")
private Set translations = new HashSet();
\\ getters and setters
}
Код: Выделить всё
class ATranslation {
@Id
@Column(name = "id", nullable = false)
private UUID id;
@ManyToOne()
@JoinColumn(name = "a_id", nullable = false)
private A a;
@Column(name = "language_code")
private String languageCode;
@Column(name = "is_default")
private Boolean isDefault = Boolean.FALSE;
// Other specific fields (for example: name, title and e.t.c)
}
Также предположим, что DTO, который я должен вернуть, должен выглядеть примерно так:
Код: Выделить всё
clas ADto {
private UUID id;
private String title;
private Set bDtoSet = new LinkedHashSet();
}
При работе с вышеупомянутыми сущностями для получения, например, сущности А с переводом на определенный язык и всех связанных сущностей B также на определенном языке я делаю запрос, подобный следующему:
Сначала я получаю объект A с необходимым языком и переводом по умолчанию:
Код: Выделить всё
public Optional findByIdAndLanguageCodeWithDefaultFallback(UUID id, String languageCode) {
QA qA = QA.a;
QATranslation qTranslation = QATranslation.aTranslation;
BooleanExpression idPredicate = qA.id.eq(id);
BooleanExpression defaultTranslationPredicate = qTranslation.isDefault.isTrue();
BooleanExpression requestedTranslationPredicate = qTranslation.language.code.eq(languageCode);
QA a = queryFactory.selectFrom(qA)
.leftJoin(qA.translations, qTranslation)
.fetchJoin()
.where(idPredicate.and(defaultTranslationPredicate).or(requestedTranslationPredicate))
.fetchOne();
return Optional.ofNullable(a);
}
Код: Выделить всё
public List findAllByAId(UUID id, String code) {
QB qB = QB.b;
QBTranslation qTranslation = QBTranslation.bTranslation;
BooleanExpression idPredicate = qB.a.id.eq(id);
BooleanExpression defaultTranslation = qTranslation.isDefault.isTrue();
BooleanExpression requestedTranslation = qTranslation.language.code.eq(code);
return queryFactory.selectFrom(qB)
.leftJoin(qB.translations, qTranslation)
.fetchJoin()
.where(idPredicate.and(defaultTranslation).or(requestedTranslation))
.fetch();
}
Код: Выделить всё
public interface AMapper {
@Mapping(target = "id", source = "a.id")
@Mapping(target = "title", source = "a.translations", qualifiedByName = "translated")
ADto toDto(A a, List bList);
@Named("translated")
default String translated(Set translations) {
String result = null;
Iterator iterator = translations.iterator();
if (translations.size() == 1) {
return iterator.next().getTitle();
}
while (iterator.hasNext()) {
ATranslation translation = iterator.next();
if (translation.getIsDefault()) {
continue;
}
result = translation.getTitle();
}
return result;
}
}
Подробнее здесь: https://stackoverflow.com/questions/787 ... es-via-jpa
Мобильная версия