Question

So i'm working on a project (JSF2, Spring3 Core, MVC, Webflow, MyBatis3, RichFaces, and a legacy Oracle 10g). The source of all of my trouble's has to do with the design of the database. The problem is that the majority of the DB tables have changing schema (bad design perhaps?). So I need to be able to support the addition & removal of extra columns.

To accommodate this i've made MyBatis pull data into a custom "universal" domain object which basically just extends a hashmap. My current issue is updating these hashmap objects. There should be a way to make it work, but I can seem to get MyBatis to co-operate. I've tried using HashMap.entrySet() & MyBatis's , but to no avail. eg.

UPDATE MYTABLE
SET 
<foreach collection="entries" index="i" item="entry" close=""  open="" separator=", ">
  #{entry.key} = #{entry.value}
</foreach>
WHERE FOO='BAR';

I've tried a custom TypeHandler but setParameter() doesn't give me enough access to do what I need. A ResultHandler didn't give me enough access to each individual result, so I couldn't use that either.

Now I know i could do something like Obj.createUpdateSqlString() and insert it into the mapper as a literal string, but thats a bit of a hack and leaves me open to SQL injection. Not to mention that would involve escaping a lot of strings, and accounting for a wide range of possible input, and unless all possibilities are covered that opens up the door for some serious bugs.

So is there an established way to do this? Or atleast a halfway decent way? I've heard a number of hardcore MyBatis advocates say they've yet to encounter a situation MyBatis couldn't handle gracefully; so MyBatis experts, please help me out!!

Was it helpful?

Solution

It sounds like they were trying to avoid using EAV tables.

You have to pick your poison when it comes to dynamically adding fields. EAV is good from a theory standpoint but has serious performance issues on large tables. While dynamically adding columns is better for query performance you have to deal with a changing table interface and dynamic sql. I wouldn't write the database off as a bad design outright.

You may want to bypass the framework you're using. Query your table schema (for Oracle look at USER_TAB_COLUMNS) and generate the insert/update scripts. Parameterize them so you are safe from injection. It will be a headache but I don't see an alternative.

OTHER TIPS

MyBatis or Hibernate both stink with crazy database schemeas. I would just use SpringJDBC or similar.

Don't try to make a round peg fit into a square hole, even if it is a really nice round peg.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top