JPA:如何只生育某些孩子?

时间:2018-11-24 16:49:14

标签: jpa spring-data-jpa spring-data

我有一些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及其所有元素,但是对于每个元素,我只需要进行一次翻译(取决于语言环境选择)

假设在数据库中我有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个结果,无论如何,每个元素的翻译仍然如此。

我想要获得每个元素两个结果(ManagedList),对于每个元素,我只希望进行一次翻译(在String语言环境中)。

我试图像

一样在JPQL中添加“提取”
...
+ "left join fetch translations.language as language "
...

但是我遇到了以下错误:

  

查询指定联接获取,但已获取的所有者   选择列表中不存在关联

有关如何实现这一目标的任何提示? 谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您应该简化模型-将Language更改为枚举(您的语言列表是有限的,是吗?)。

然后,尝试在查询中添加'distinct'并将'join'替换为'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);