JPA: Как получить только определенных детей? - PullRequest
0 голосов
/ 24 ноября 2018

У меня есть ManagedList, который содержит список ListElement.Эти ListElement содержит список перевода.

public class ManagedList {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name", nullable = false, length = 50)
    private String name;

    @OneToMany(mappedBy = "managedList", fetch = FetchType.LAZY)
    private List<ListElement> listElement;
}
public class ListElement {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name= "listElement_id")
    private List<ElementTranslation> translations;

}
public class ElementTranslation {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(fetch = FetchType.LAZY)
    private Language language;

    @ManyToOne(fetch = FetchType.LAZY)
    private ListElement listElement;

    @Column(name = "text", nullable = true, length = 200)
    private String text;

}
public class Language {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name", nullable = false, length = 50)
    private String name;

}

Я хотел бы получить все ManagedList со всеми их элементами, но для каждого элемента мне нужен только 1 перевод (в зависимости от выбора локали)

Допустим, в БД у меня есть 2 ManagedList, у каждого есть 3 элемента, у каждого элемента есть 2 перевода.

С:

public List<ManagedList> findAllByOrderByNameAsc();

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

Я пытался с:

@Query("select managedList from ManagedList managedList "
            + "left join managedList.listElement as listElement "
            + "left join listElement.translations as translations "
            + "left join  translations.language as language "
            + "where language.name = :locale ")
   List<ManagedList> getVocab(@Param("locale") String locale);

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

Я хотел бы получить2 результата (ManagedList) с каждым из их элементов, и для каждого элемента я хотел бы только 1 перевод (один для языкового стандарта String).

Я пытался добавить «выборку» в JPQL, как

...
+ "left join fetch translations.language as language "
...

Но я получил следующую ошибку:

в запросе указано объединение выборки, но владелец извлеченной ассоциации не присутствовал в списке выбора

Любые советы о том, как этого добиться?Thx!

1 Ответ

0 голосов
/ 26 ноября 2018

Я думаю, вам следует упростить вашу модель - замените Language на enum (у вас список языков ограничен, да?).

Затем попробуйте добавить «отличный» к вашему запросу и заменить »join 'with' join fetch ':

@Query("select distinct " + 
        "  ml " +
        "from " + 
        "  ManagedList ml "
        "  join fetch ml.listElement le " +
        "  join fetch le.translations ts " +
        "where " + 
        "  ts.language = ?1")
List<ManagedList> getVocab(Language lang);
...