ibatis-user-java mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Shannon, Bryan" <BShan...@Tribune.com>
Subject Poll: comparing old and new beans before persisting
Date Mon, 28 Apr 2008 16:58:51 GMT
I am fully aware that iBatis isn't a full ORM (and thank goodness it's
not)...
 
But there are still places where, in a fully normalized db schema, there
isn't a one bean per table-row in the database...
 
There are often one to many relationships and join tables, etc.  I'm
wondering if/how anyone else out there has tried to make determining
which rows to insert/update/delete an easier task.
 
Do you compare the beans (before and after) property-by-property? 
 
Did you write convenience functions that compare the list properties of
to beans to each other to figure out which is an insert, an update, or a
delete?
 
I'm asking this list because I've thrown some convenience classes
together that make it much easier to compare an old bean with a new bean
and do the appropriate ibatis stuff...
 
It basically is used something like this:
 
// Assuming a bean that has a collection property of "favoriteFoods":
new CollectionPersister(sqlMap, oldBean, newBean, "favoriteFoods",
"MyMap.deleteFavoriteFood", "MyMap.updateFavoriteFood",
"MyMap.insertFavoriteFood").persist();
 
By default, the persister compares the old values and new values for the
favoriteFoods property, and calls the appropriate sql map with that
favorite food bean as a parameter...
 
Of course, sometimes sometimes you need to send in a map or some other
bean as a parameter to the map to link to entities together, so I have
hooks that allow me to override this basic functionality:
 
 
new CollectionPersister(sqlMap, oldBean, newBean, "favoriteFoods",
"MyMap.deleteFavoriteFood", "MyMap.updateFavoriteFood",
"MyMap.insertFavoriteFood") {
 
    // Overriding the default behavior of sending a Food element to the
update map as a parameter; it needs a map instead...
    public void getUpdateMapParam(Object listElement) {
        Map tmp = new HashMap();
        tmp.put("person_id", personId);
        tmp.put("favorite_food_id", ((Food)listElement).getId());
        return tmp;
    }
 
}.persist();
 

The persister is extendable and has some complex logic that determines
which elements of the list were actually inserted/updated/deleted.
 
Has anyone else done things like this?  I was able to take about 1000
lines of my dao and shrink it into about 1 line per collection property
(I have a huge object graph). 
 
Anyone else interested?  As I started to retrofit a dao that has grown
with age and saw the usefulness of something like this, I thought of you
guys on the list. :-)
 
I don't know if anyone else out there has tried to solve the problem of
trying to only update what needs to be updated, or does this old vs. new
comparison.  There are only a few ways to handle this problem in general
(it seems to me):
 
1) Just always update, even if it doesn't change.  "Drop and Swap"
collections (that are persisted to your join tables in the db).
2) Somehow add properties to your beans to keep track of what changed (a
"dirty flag")
3) Do what hibernate does and pollute your bean with magical proxies,
which forces you to have your hibernate+100 dependencies on your client
tier's classpath.  (GRRR; a Swing GUI in my case!)
4) Send the old and the new and compare them, the more automated, the
better.
 
Tell your stories!  I'm sure someone else out here would like to hear
them.
 
Thanks!
-Bryan Shannon
Tribune Media Services
 

Mime
View raw message