Query by Example on associations
Asked Answered
B

3

6

It's very frustrating that you cannot use QBE on associations.

I have a large datatable with about 8 many-to-one columns. There is a a drop-down list for every column to filter the table.

Let's assume the following:

Table User

User { id, UserStatus, UserAuthorization }

I want to use this code:

Criteria crit = getSession().createCriteria(class);
crit.add(Example.create(userObject));

This does not work on the following example userObject:

User id=1 { UserStatus=Active, UserAuthorization=Admin }

because QBE doesn't support collections.

One way to solve this is to use it this way:

crit.createCriteria("UserStatus").add(Example.create(userStatusObject));
crit.createCriteria("UserAuthorization").add(Example.create(userAuthorizationObject));

My question is how this can be programmed dynamically just with the given User object. Is there another way than using QBE?

Barman answered 16/2, 2012 at 10:45 Comment(4)
doing it by hand with .add(Restriction.eq())?Maurine
I try to avoid that... the whole point behind QBE is to not do things by handBarman
i just answered "Is there another way than using QBE?" :DMaurine
Ah sorry :D That's my solution now, but I thought of a more sophisticated one ;)Barman
M
3

you can combine QBE and normal Expressions to handle the parts QBE doesnt support

Criteria crit = getSession().createCriteria(class);
    .add(Example.create(userObject));
    .add(Expression.eq("UserStatus", userObject.getUserStatus()));
Maurine answered 16/2, 2012 at 17:24 Comment(1)
Thanks, are there any ways to make this dynamic?Barman
C
1

Here's a generic answer that I found worked for me inside of my repository base, using reflection:

protected T GetByExample(T example)
{
    var c = DetachedCriteria.For<T>().Add(Example.Create(example).ExcludeNone());
    var props = typeof (T).GetProperties()
        .Where(p => p.PropertyType.GetInterfaces().Contains(typeof(IEntityBase)));
    foreach (var pInfo in props)
    {
        c.Add(Restrictions.Eq(pInfo.Name, pInfo.GetValue(example)));
    }
    return Query(c);
}

Note that all of my entities inherit from IEntityBase, which allowed me to find just those foreign key references from the object properties so I could add them to the criteria. You'll have to provide some way to execute the query (i.e. c.GetExecutableCriteria(Session))

Cammiecammy answered 10/3, 2015 at 21:12 Comment(0)
E
0

Here is the code which can be used for every entity to use the query by example in hibernate.

  /**
                 * This method will use for query by example with association 
                 * @param exampleInstance the persistent class(T) object
                 * @param restrictPropertyName the string object contains the field name of the association
                 * @param restrictPropertyValue the association object 
                 * @return list the persistent class list
                 */
public List<T> queryByExampleWithRestriction(T exampleInstance, String restrictPropertyName, Object restrictPropertyValue) {
            log.info("Inside queryByExampleWithRestriction method of GenericHibernateDAO");
            List<T> list = null;
            try {
                Criteria criteria = getSession().createCriteria(exampleInstance.getClass());  
                Example example =  Example.create(exampleInstance);
                criteria.add(example);
                criteria.add(Restrictions.eq(restrictPropertyName, restrictPropertyValue));
                list = criteria.list();
                log.info("Executed the queryByExampleWithRestriction query with criteria successfully!");
            } catch(HibernateException e){
                throw (e);
            }
            finally{
                this.closeSession();
            }
            return list;  
        }
Enneagon answered 10/12, 2016 at 5:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.