Hibernate JPA类别语言关系
我正在使用JPA/Hibernate+Spring构建一个基于类别的web应用程序多语言 我目前构建了这三个bean/实体:Category、CategoryLanguage和Language 类别:Hibernate JPA类别语言关系,hibernate,jpa,eclipselink,Hibernate,Jpa,Eclipselink,我正在使用JPA/Hibernate+Spring构建一个基于类别的web应用程序多语言 我目前构建了这三个bean/实体:Category、CategoryLanguage和Language 类别: @Entity public class Category implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; @ManyToOn
@Entity
public class Category implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
private Category father;
@OneToMany(mappedBy = "father")
private List<Category> children;
@OneToMany(mappedBy="category")
private List<CategoryLanguage> categoryLanguages;
@Entity
public class CategoryLanguage implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
Category category;
@Column(length = 20, nullable = false)
private String name;
@ManyToOne
private Language language;
和语言
public class Language implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(length=2)
private String id; // en, de, fr, it, es,...
@Column(length=25)
private String name; // English, Deutsch, Français,...
打电话
from Category c join c.categoryLanguages cl where c.father = null and cl.language.id = :lang
它返回具有正确语言的第一级类别,但包含作为子级的所有语言
为每种语言提取子语言,而不是我在查询中选择的语言。
我能做些什么来解决这个问题?我不能在JPQL中使用“joinon”,可以吗?请确保使用
FetchType.EAGER
使用方法如下:
SELECT c FROM Cagegory c INNER JOIN c.categoryLanguages l WHERE c.father = null AND l.id = :languageId
@OneToMany(mappedBy = "father", fetch = FetchType.EAGER)
private List<Category> children = new ArrayList();
@OneToMany(mappedBy="category", fetch = FetchType.EAGER)
private List<CategoryLanguage> categoryLanguages = new ArrayList();
从Cagegory c内部连接c.categoryLanguages l中选择c,其中c.father=null,l.id=:languageId
@OneToMany(mappedBy=“father”,fetch=FetchType.EAGER)
private List children=new ArrayList();
@OneToMany(mappedBy=“category”,fetch=FetchType.EAGER)
private List categoryLanguages=new ArrayList();
确保使用FetchType.EAGER
使用方法如下:
SELECT c FROM Cagegory c INNER JOIN c.categoryLanguages l WHERE c.father = null AND l.id = :languageId
@OneToMany(mappedBy = "father", fetch = FetchType.EAGER)
private List<Category> children = new ArrayList();
@OneToMany(mappedBy="category", fetch = FetchType.EAGER)
private List<CategoryLanguage> categoryLanguages = new ArrayList();
从Cagegory c内部连接c.categoryLanguages l中选择c,其中c.father=null,l.id=:languageId
@OneToMany(mappedBy=“father”,fetch=FetchType.EAGER)
private List children=new ArrayList();
@OneToMany(mappedBy=“category”,fetch=FetchType.EAGER)
private List categoryLanguages=new ArrayList();
您的查询要求完整的类别实体,因此您无法严格使用JPA实现您想要的。JPA要求返回的类别实体反映数据库中的数据-这包括所有CategoryLanguage,而不管它们在选择查询中可能对应的语言
您可能想做的是以不同的方式重新排列查询。在本例中,查询与所需语言关联的CategoryLanguage实体,然后使用它获取类别。category->CategoryLanguage关系仍将填充,但查询只返回表示所需语言的CategoryLanguage,而不返回任何其他语言。按类别为这些设置关键帧,以便在需要时更轻松
大多数提供程序都允许直接向映射添加过滤条件,或者您甚至可以使用只返回部分实体的查询,但我提醒您不要走这条路。一旦这样做,就很难正确地维护应用程序和管理数据,并可能最终限制缓存等性能选项。例如,一旦您拥有了所有的分部类别实体,并且想要添加新的CategoryLanguage或进行任何其他更改,您将如何处理它?合并将不起作用,因为它将导致数据库列表中没有任何CategoryLanguage您的查询要求完整的类别实体,因此您无法严格使用JPA实现您想要的目标。JPA要求返回的类别实体反映数据库中的数据-这包括所有CategoryLanguage,而不管它们在选择查询中可能对应的语言 您可能想做的是以不同的方式重新排列查询。在本例中,查询与所需语言关联的CategoryLanguage实体,然后使用它获取类别。category->CategoryLanguage关系仍将填充,但查询只返回表示所需语言的CategoryLanguage,而不返回任何其他语言。按类别为这些设置关键帧,以便在需要时更轻松
大多数提供程序都允许直接向映射添加过滤条件,或者您甚至可以使用只返回部分实体的查询,但我提醒您不要走这条路。一旦这样做,就很难正确地维护应用程序和管理数据,并可能最终限制缓存等性能选项。例如,一旦您拥有了所有的分部类别实体,并且想要添加新的CategoryLanguage或进行任何其他更改,您将如何处理它?合并将不起作用,因为它将导致数据库列表中没有任何CategoryLanguage是否需要在子对象中初始化
新ArrayList()
?是否要按语言(递归)检索类别及其子类别?不可能,我将删除它。在第二个问题上是的:)是否需要在子类中初始化new ArrayList()
?是否希望通过语言(递归)检索类别及其子类别?不可能,我将删除它。第二个问题是肯定的:)谢谢,但由于双方都很急切,它会抛出多个包。例外:无法同时提取多个包。通过在categoryLanguages上设置Earge only,它仍然会加载所有语言的categoryLanguages:SThank you,但同时使用这两种Earge,它会抛出MultipleBagFetchException:无法同时获取多个包。通过仅在categoryLanguages上设置EAGER,它仍然会加载所有语言的categoryLanguages:S