Hibernate Create Criteria to Join the Same Table Twice - Tried 2 Approach with 2 Difference Error

Hibernate Create Criteria to join the same table twice - tried 2 approach with 2 difference error

There is an old Hibernate bug HHH-879 on the problem of org.hibernate.QueryException: duplicate association path opened 2005 and still open...

Other issue is closed without solution HHH-7882

So the option 1) is rather not suitable.

But in the comments of the above bug an usefull workaround is mentioned using exists

So use twice sqlRestriction with exists and a correlated subquery filtering the propper category. You will get only companies connected to both categories.

crit.add( Restrictions.sqlRestriction( 
"exists (select null from Company_Customercategory a where {alias}.company_Id = a.company_Id and a.CUSTOMERCATEGORYID = ?)",
1, IntegerType.INSTANCE ) );
crit.add( Restrictions.sqlRestriction(
"exists (select null from Company_Customercategory a where {alias}.company_Id = a.company_Id and a.CUSTOMERCATEGORYID = ?)",
6, IntegerType.INSTANCE ) );

This leads to the following query which provides the correct result

select this_.COMPANY_ID as COMPANY_ID1_2_0_, this_.COMPANY_NAME as COMPANY_NAME2_2_0_ 
from COMPANIES this_
where exists (select null from Company_Customercategory a
where this_.company_Id = a.company_Id and a.CUSTOMERCATEGORYID = ?) and
exists (select null from Company_Customercategory a
where this_.company_Id = a.company_Id and a.CUSTOMERCATEGORYID = ?)

Join two table using Criteria in Hibernate?

I don't think it is possible to join the same association twice with Criteria

You can find the related JIRA here that is still open.

Iteration to create createCriteria. Getting error org.hibernate.QueryException: duplicate association path

I was having the same problem and i search for hours and hours.

Here is what worked for me :

public Images getRandomImagesInGallerys(String[] galleryList) {

String query = "from Images ";
boolean first = true;

for(String string : galleryList) {
if(first){
query+="where '"+string+"' member of galleries ";
first=false;
} else {
query+="or '"+string+"' member of galleries ";
}
}

entityManager.createQuery(query, Images.class).getResultList();
}

Hope it help someone.

JPA Criteria Query - How to Avoiding Duplicate Joins

A suggestion for avoid it is to use a builder class to encapsulate the joins , see below.

public class AccountCriteriaBuilder {

CriteriaBuilder cb;
CriteriaQuery<Account> cq;

// JOINS INSTANCE
Root<Account> accountRoot;
Join<Account,Person> personJoin;
Join<Person,Address> personAddressJoin;

public AccountCriteriaBuilder(CriteriaBuilder criteriaBuilder) {
this.cb = criteriaBuilder;
this.cq = cb.createQuery(Account.class);
this.accountRoot = cq.from(Account.class);
}

public CriteriaQuery buildQuery() {
Predicate[] predicates = getPredicates();
cq.select(accountRoot).where(predicates);
return cq;
}

public Predicate[] getPredicates() {

List<Predicate> predicates = new ArrayList<Predicate>();

predicates.add(cb.equal(getPersonJoin().get(Person_.name), "Roger"));
predicates.add(cb.greaterThan(getPersonJoin().get(Person_.age), 18));
predicates.add(cb.equal(getPersonAddressJoin().get(Address_.country),"United States"));

return predicates.toArray(new Predicate[predicates.size()]);
}

public Root<Account> getAccountRoot() {
return accountRoot;
}

public Join<Account, Person> getPersonJoin() {
if(personJoin == null){
personJoin = getAccountRoot().join(Account_.person);
}
return personJoin;
}

public Join<Person, Address> getPersonAddressJoin() {
if(personAddressJoin == null){
personAddressJoin = getPersonJoin().join(Person_.address);
}
return personAddressJoin;
}

}

The “ace in the hole” is the lazy loads for each required join instance, it will avoid duplicate joins and also to simplify the navigation process.

Finally, just call the builder like below :

AccountCriteriaBuilder criteriaBuilder = new AccountCriteriaBuilder(em.getCriteriaBuilder());
TypedQuery<Account> query = em.createQuery(criteriaBuilder.buildQuery());
List<Account> result = query.getResultList();

Enjoy :)

org.hibernate.QueryException: duplicate association path for @ManyToOne Criteria

I think you need to provide an alias, so you should change your code this way:

Criteria criteria = getSessionFactory().getCurrentSession().createCriteria(Activity.class);

criteria.createCriteria("activityType", "at")
.add(
Restrictions.like("at.name", value.toString(), MatchMode.START));

org.hibernate.QueryException: duplicate association path: metaData

I got the answer thanks Pritesh Shah, here is the solution

    Criteria criteria = getSession().createCriteria(Employee.class, "employee").createCriteria("metaData", "mData").createCriteria("currentRunningContract", "currentContract");
if (key.equals("directorate")) {
criteria.createCriteria("currentContract."+key).add(Restrictions.in("id", (Long[])parameters.get(oKey)));
}Blahblah etc...

I used the aliases that I created in one shot at the firs lone :)

Cya all :)

Refactor closure criteria to fix maximum number of expressions in a list is 1000

Found a solution

def collatedFileList = paketInstance.dateien.id.toList().collate(999)
def addCriteriaClosure = { criteriaList ->
criteriaList.or {
collatedFileList.each {
l -> criteriaList.inList("id", l.toList())
}
}
}
  1. Resolves the problem I had to face
  2. Learned a lot about the Closure / Criteria thing

Hibernate Criteria multiple where

Try creating Predicate and adding them to the criteria: Predicate condition = builder.equal(...); criteria.add(condition); – Fran Montero 23 hours ago

Trying to implement a criteria query using Hibernate, getting cannot resolve method error

You get the error because using Path#get(String) is not type-safe. Use Metamodel expressions if you want the compiler to correctly interpret the type you want to be returned.
If you use string parameter, you need to specify the type like that:

Expression<Integer> expr = root.<Integer> get("cubicCapacityMax");

Using Metamodel, the same expression could be obtained in this way:

Expression<Integer> expr = root.get(BaseQuote_.cubicCapacityMax);

Also note that the string parameter must correspond to the name of a property (cubicCapacityMax in this case) and not to the db name of the field (cc_max).

See also:

  • Oracle's Java EE Tutorial - Using the Criteria API and Metamodel API to Create Basic Typesafe Queries


Related Topics



Leave a reply



Submit