Hibernate 的 Criteria With Example 和 Query Return 不同的结果
Hibernate's Criteria With Example And Query Return different results
我在应用程序中使用 hibernate 进行实体持久化,但是当我使用 HQL 获取实体时它工作正常并且 returns 是 table 中存在的实体的确切数量但是当我使用 hibernate 的标准和示例它 return 第一个实体两次,因此导致 returning 一个实体多于 table
中实际存在的实体
实体定义
public class ItemParentCategory {
@Id
@GeneratedValue
private long id;
private String name;
@OneToMany(mappedBy = "itemParentCategory",fetch = FetchType.EAGER)
@JsonIgnore
private List<ItemSubCategory> itemSubCategorys;
@OneToOne
private ItemMainCategory itemMainCategory;
@JsonIgnore
private String summary;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ItemSubCategory> getItemSubCategorys() {
return itemSubCategorys;
}
public void setItemSubCategorys(List<ItemSubCategory> itemSubCategorys) {
this.itemSubCategorys = itemSubCategorys;
}
public ItemMainCategory getItemMainCategory() {
return itemMainCategory;
}
public void setItemMainCategory(ItemMainCategory itemMainCategory) {
this.itemMainCategory = itemMainCategory;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
}
获取实体的代码
@Override
public List<ItemParentCategory> getAllItemParentCategoryUnderItemMainCategory(long itemMainCategoryId) {
//This code works fine
Query query = sessionFactory.getCurrentSession().getNamedQuery("ItemParentCategory.getAllItemParentCategoryUnderItemMaincategory");
query.setParameter("itemMainCategoryId", itemMainCategoryId);
return query.list();
//This Code return undesired result
/*Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ItemParentCategory.class);
ItemParentCategory itemParentCategory = new ItemParentCategory();
ItemMainCategory itemMainCategory = new ItemMainCategory();
itemMainCategory.setId(itemMainCategoryId);
itemParentCategory.setItemMainCategory(itemMainCategory);
Example example = Example.create(itemParentCategory);
criteria.add(example);
return criteria.list();*/
}
我用的HQL
FROM ItemParentCategory itemParentCategory WHERE itemParentCategory.itemMainCategory.id = :itemMainCategoryId
尝试在您的查询中添加不同的
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
这里发生的事情是因为您已将 ItemParentCategory 映射到 ItemSubcategory 作为 FetchType.EAGER。
现在,这不会影响您的 HQL 查询,因为 HQL 查询不会遵循 EAGER 映射,并且要急切获取 HQL 中的子类别,您必须在查询中明确定义 FETCH JOIN。因此,在这种情况下一切都很好。
如果您将 HQL 更改为如下所示,您可能会遇到相同的重复问题:
FROM ItemParentCategory ipc JOIN FETCH ipc.itemSubCategorys WHERE ipc.itemMainCategory.id = :itemMainCategoryId
请参阅以下两个常见问题解答:
HQL queries always ignore the setting for outer-join or fetch="join"
defined in mapping metadata. This setting applies only to associations
fetched using get() or load(), Criteria queries, and graph navigation
示例查询必须以与标准查询类似的方式工作,并且您有 fetch = FetchType.EAGER
Hibernate 正在执行显式连接。您应该打开 SQL 日志记录以查看每种情况下实际生成的 SQL。
我在应用程序中使用 hibernate 进行实体持久化,但是当我使用 HQL 获取实体时它工作正常并且 returns 是 table 中存在的实体的确切数量但是当我使用 hibernate 的标准和示例它 return 第一个实体两次,因此导致 returning 一个实体多于 table
中实际存在的实体实体定义
public class ItemParentCategory {
@Id
@GeneratedValue
private long id;
private String name;
@OneToMany(mappedBy = "itemParentCategory",fetch = FetchType.EAGER)
@JsonIgnore
private List<ItemSubCategory> itemSubCategorys;
@OneToOne
private ItemMainCategory itemMainCategory;
@JsonIgnore
private String summary;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ItemSubCategory> getItemSubCategorys() {
return itemSubCategorys;
}
public void setItemSubCategorys(List<ItemSubCategory> itemSubCategorys) {
this.itemSubCategorys = itemSubCategorys;
}
public ItemMainCategory getItemMainCategory() {
return itemMainCategory;
}
public void setItemMainCategory(ItemMainCategory itemMainCategory) {
this.itemMainCategory = itemMainCategory;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
}
获取实体的代码
@Override
public List<ItemParentCategory> getAllItemParentCategoryUnderItemMainCategory(long itemMainCategoryId) {
//This code works fine
Query query = sessionFactory.getCurrentSession().getNamedQuery("ItemParentCategory.getAllItemParentCategoryUnderItemMaincategory");
query.setParameter("itemMainCategoryId", itemMainCategoryId);
return query.list();
//This Code return undesired result
/*Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ItemParentCategory.class);
ItemParentCategory itemParentCategory = new ItemParentCategory();
ItemMainCategory itemMainCategory = new ItemMainCategory();
itemMainCategory.setId(itemMainCategoryId);
itemParentCategory.setItemMainCategory(itemMainCategory);
Example example = Example.create(itemParentCategory);
criteria.add(example);
return criteria.list();*/
}
我用的HQL
FROM ItemParentCategory itemParentCategory WHERE itemParentCategory.itemMainCategory.id = :itemMainCategoryId
尝试在您的查询中添加不同的
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
这里发生的事情是因为您已将 ItemParentCategory 映射到 ItemSubcategory 作为 FetchType.EAGER。
现在,这不会影响您的 HQL 查询,因为 HQL 查询不会遵循 EAGER 映射,并且要急切获取 HQL 中的子类别,您必须在查询中明确定义 FETCH JOIN。因此,在这种情况下一切都很好。
如果您将 HQL 更改为如下所示,您可能会遇到相同的重复问题:
FROM ItemParentCategory ipc JOIN FETCH ipc.itemSubCategorys WHERE ipc.itemMainCategory.id = :itemMainCategoryId
请参阅以下两个常见问题解答:
HQL queries always ignore the setting for outer-join or fetch="join" defined in mapping metadata. This setting applies only to associations fetched using get() or load(), Criteria queries, and graph navigation
示例查询必须以与标准查询类似的方式工作,并且您有 fetch = FetchType.EAGER
Hibernate 正在执行显式连接。您应该打开 SQL 日志记录以查看每种情况下实际生成的 SQL。