Mayank Sharma
Mayank Sharma

Reputation: 712

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

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

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

Upvotes: 0

Views: 899

Answers (2)

Alan Hay
Alan Hay

Reputation: 23226

What is happening here is as a result of the fact that you have mapped ItemParentCategory to ItemSubcategory as FetchType.EAGER.

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. Therefore everything is fine in this scenario.

If your changed your HQL to be as below you would most have the same duplicates issue:

FROM ItemParentCategory ipc JOIN FETCH ipc.itemSubCategorys WHERE 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_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. This setting applies only to associations fetched using get() or load(), Criteria queries, and graph navigation

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. You should turn on SQL logging to view the actual SQL generated in each case.

Upvotes: 1

Rafael Zeffa
Rafael Zeffa

Reputation: 2414

try put a distinct in your query

query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Upvotes: 0

Related Questions