ncthuc / hibernate-generic-dao

Automatically exported from code.google.com/p/hibernate-generic-dao
0 stars 0 forks source link

Add support for findByExample #27

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I'm seriously considering using the hibernate-generic-dao library in a
project.  I'm doing some major refactoring and wish to really simplify the
service layer.  This project looks very useful, especially the Search features.

However, my project's existing DAO's are using something similar to the
findByExample(T entity) methods shown here:
http://www.hibernate.org/328.html

Would it be possible to add the following methods (or something similar) to
the DAOs?

public List<T> findByFilter(T filterEntity);
public List<T> findByFilter(T filterEntity, String[] excludeProperty);
public int countByFilter(T filterEntity);
public int countByFilter(T filterEntity, String[] excludeProperty);

Or perhaps modify the Search object so that it can be instantiated with an
example entity (a filter entity)?

I like the Search object for doing fine tuned searching.  But there are
many cases when an example instance of the entity would be simpler to use
as a filter.

I think I'll just start implementing this myself.  But it would be nice to
hear opinions about it and if my efforts could be contributed back to the
project.

Original issue reported on code.google.com by yowza...@gmail.com on 23 Feb 2009 at 8:26

GoogleCodeExporter commented 8 years ago
Here is an initial attempt at adding findByExample() features.  Let me know 
what you
think.

Original comment by yowza...@gmail.com on 23 Feb 2009 at 6:09

Attachments:

GoogleCodeExporter commented 8 years ago
I'll have time to look at your comments more in depth in a few days, but I'd 
like to 
make some comments now that may be helpful. I haven't looked at your patch yet, 
so 
sorry if what I say does not apply.

You may or may not know that the project is architected so that you can use 
your own 
implementations of of the Generic DAOs or extend whats there and use that as 
your DAO 
base. Your idea of using an example to build a search object is probably the 
best way 
to plug extra functionality into the framework. I'm excited to see what you 
come up 
with for this. I do think this could be a good feature to add to the framework.

I'll have a closer look at this in a couple days. Thanks for your comments. I 
hope 
this project will be of use to you. My plan is to make the upcoming version or 
so a 
1.0 version. I think what's there is pretty solid and complete.

Original comment by dwolvert on 26 Feb 2009 at 3:19

GoogleCodeExporter commented 8 years ago
Thanks for your reply.  The patch actually adds findByFilter and countByFilter
methods to the DAOs themselves.  I guess I should have considered creating my 
own
implementing of Generic DAO, but it seemed like a useful thing to make 
available for
everyone who wanted to use this library.  Maybe that is just because of my use 
case
however.

My project is being built with Apache Wicket which has features for creating 
elements
such as lists of entities that can be sorted, paginated, filtered, etc.  To do 
the
filtering, you pass an instance of an entity that it uses as an example.  So it
really simplifies things if the DAO itself can handle using an entity as an 
example.
Also, the Wicket DataProvider has a size() method that needs implementing, and I
wasn't thrilled with the searchAndCount approach since all I want is the size, I
don't want to fetch data too.

However, I implemented this very quickly, so I'm sure there are probably better
designs or solutions.  I did first consider using the search object and passing 
an
example entity to it before implementing it into the DAO itself.  It sounds 
like you
think that might be the right approach too.  

My thoughts were that the Search object would need to use reflection to figure 
out
how to build the search object based on the entity's property types and values. 
But I
quickly decided that was too much to take on since I needed a quick solution.  
It was
so much easier to just do this in the DAO:

protected <T> List<T> _findByFilter(T filterEntity, String[] excludeProperty) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        if (filterEntity != null) {
            Example example =  Example.create(filterEntity);
            if (excludeProperty != null) {
                for (String exclude : excludeProperty) {
                    example.excludeProperty(exclude);
                }
            }
            crit.add(example);
        }
        return crit.list();
};

(Note that the code above differs from the patch as I fixed a bug)

Original comment by yowza...@gmail.com on 27 Feb 2009 at 10:24

GoogleCodeExporter commented 8 years ago
Enhancement marked as accepted. Find by example will be planned for an upcoming 
version.

Original comment by dwolvert on 11 Mar 2009 at 8:59

GoogleCodeExporter commented 8 years ago
yowzator,

I finally had a chance to review your comments in depth. When we do add find by 
example to the framework, I think we will use introspection to do it manually. 
This 
way we will be able to preserve all of our other search options while using 
find by 
example.

For now, my suggestion for you is to put your new DAO methods in new 
Generic/General 
DAO classes that extend from the frameworks Generic/General DAO classes. This 
way you 
keep the framework source unchanged, which makes future upgrades much easier 
for you.

You also made a comment about searchAndCount() being too much. Did you notice 
the 
count() method?

Thanks for the idea of adding find by example to the framework.

Original comment by dwolvert on 11 Mar 2009 at 9:13

GoogleCodeExporter commented 8 years ago
dwolvert,

Sounds great!  I assume you want to add search by example as a feature of Search
instead of the DAO directly?

I'm not sure why I said something about the searchAndCount() before.  I had 
reviewed
the code and saw the count() method, but I recall thinking there was a 
limitation for
some reason.  I just looked again and the issue didn't jump out at me.  Maybe 
it had
something to do with my own really bad implementation of countByFilter:

protected int _countByFilter(Object filterEntity) {
    return _countByFilter(filterEntity,null);
};

protected int _countByFilter(Object filterEntity, String[] excludeProperty) {
    return _findByFilter(filterEntity,excludeProperty).size();
};

protected <T> List<T> _findByFilter(T filterEntity) {
    return _findByFilter(filterEntity,null);
};

protected <T> List<T> _findByFilter(T filterEntity, String[] excludeProperty) {
        Criteria crit = getSession().createCriteria(getPersistentClass());
        if (filterEntity != null) {
            Example example =  Example.create(filterEntity);
            if (excludeProperty != null) {
                for (String exclude : excludeProperty) {
                    example.excludeProperty(exclude);
                }
            }
            crit.add(example);
        }
        return crit.list();
};

Anyway, I assume that when find by example is added, there will be a way to do a
count by example too.  So we can leave this alone for now.

Original comment by yowza...@gmail.com on 11 Mar 2009 at 10:00

GoogleCodeExporter commented 8 years ago

Original comment by dwolvert on 13 Mar 2009 at 4:40

GoogleCodeExporter commented 8 years ago
This feature will be available in 0.4.3

Original comment by dwolvert on 30 Apr 2009 at 4:41

GoogleCodeExporter commented 8 years ago
Feature is in 0.4.3

Original comment by dwolvert on 1 May 2009 at 8:47