简体   繁体   English

Hibernate的带有示例和查询的条件返回不同的结果

[英]Hibernate's Criteria With Example And Query Return different results

I am using hibernate for entity persistence in application however when i use HQL to fetch entities it works fine and returns the exact number of entities that is there in a table however when i use the hibernate's criteria with Example it return first entity twice and thus results in returning one entity more then what is actually there in the table 我正在使用hibernate进行应用程序中的实体持久化,但是当我使用HQL来获取实体时,它可以正常工作并返回表中存在的实体的确切数量,但是当我将hibernate的条件与Example一起使用时,它会返回第一个实体两次,因此结果返回一个实体多于表中实际存在的内容

Entity Definition 实体定义

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;
}

} }

Code For Fetching Entities 实体获取代码

@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 I used 我使用的HQL

FROM ItemParentCategory itemParentCategory WHERE itemParentCategory.itemMainCategory.id = :itemMainCategoryId

What is happening here is as a result of the fact that you have mapped ItemParentCategory to ItemSubcategory as FetchType.EAGER. 由于您已将ItemParentCategory映射为FetchType.EAGER到ItemSubcategory,因此发生了这种情况。

Now, this does not affect your HQL query as HQL queries will not respect the EAGER mapping and to eager fetch the sub categories in HQL you would have to explicitly define a FETCH JOIN in your query. 现在,这不会影响您的HQL查询,因为HQL查询将不遵守EAGER映射,并且要获取HQL中的子类别,您必须在查询中明确定义FETCH JOIN。 Therefore everything is fine in this scenario. 因此,在这种情况下,一切都很好。

If your changed your HQL to be as below you would most have the same duplicates issue: 如果您将HQL更改为如下所示,则大多数情况下会出现相同的重复问题:

FROM ItemParentCategory ipc JOIN FETCH ipc.itemSubCategorys WHERE ipc.itemMainCategory.id = :itemMainCategoryId 从ItemParentCategory ipc加入联接ipc.itemSubCategorys其中ipc.itemMainCategory.id =:itemMainCategoryId

See the following two FAQs: 请参阅以下两个常见问题解答:

https://developer.jboss.org/wiki/HibernateFAQ-AdvancedProblems#jive_content_id_Hibernate_does_not_return_distinct_results_for_a_query_with_outer_join_fetching_enabled_for_a_collection_even_if_I_use_the_distinct_keyword https://developer.jboss.org/wiki/HibernateFAQ-AdvancedProblems#jive_content_id_Hibernate_does_not_return_distinct_results_for_a_query_with_outer_join_fetching_enabled_for_a_collection_even_if_I_use_the_distinct_keyword

https://developer.jboss.org/wiki/HibernateFAQ-AdvancedProblems#jive_content_id_Hibernate_ignores_my_outerjointrue_or_fetchjoin_setting_and_fetches_an_association_lazily_using_n1_selects https://developer.jboss.org/wiki/HibernateFAQ-AdvancedProblems#jive_content_id_Hibernate_ignores_my_outerjointrue_or_fetchjoin_setting_and_fetches_an_association_lazily_using_n1_selects

HQL queries always ignore the setting for outer-join or fetch="join" defined in mapping metadata. HQL查询始终忽略映射元数据中定义的external-join或fetch =“ join”的设置。 This setting applies only to associations fetched using get() or load(), Criteria queries , and graph navigation 此设置仅适用于使用get()或load(), Criteria查询和图导航获取的关联

Query by Example then must work in a similar way to Criteria Queries and where you have fetch = FetchType.EAGER Hibernate is doing an explicit join. 然后,按示例查询必须以与条件查询类似的方式工作,并且在其中fetch = FetchType.EAGER Hibernate正在进行显式fetch = FetchType.EAGER You should turn on SQL logging to view the actual SQL generated in each case. 您应该打开SQL日志记录以查看每种情况下生成的实际SQL。

尝试在您的查询中添加一个独特的

query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM