Ok, that's some good information, I understand that you should marshall your objects with care. Unfortunately for me at some point I will have to marshall every single one of my database rows into an object graph. However what I took from your advice was not to be so stingy in re-using the session objects. So if I do something like this:
for (id : ids) { SqlSession session2 = sessionMapper.openSession(); MyObject o = session2.select("getOne", id.getActualId()); session2.close(); } Now memory usage is pretty good! However now performance is terrible. In attempting to rectify this I tried to put in a custom cache implementation, logging cache access to see how it was performing. I noticed it was never actually using the cache (never doing cache.putObject). I noticed that according to this discussion: http://markmail.org/search/?q=select+commit+cache+list%3Aorg.apache.ibatis.user-java#query:select%20commit%20cache%20list%3Aorg.apache.ibatis.user-java+page:1+mid:4mmwki3dnp57gweu+state:results ...commits don't occur (and thus cache fill doesn't occur) unless a transaction is committed. So for a pure read-only use case of the db the cache won't be very useful, right? Additionally, putting in a "session2.commit()" before the call to close() causes the following error (which I assume, but don't know is caused by committing when nothing actually needs to be comitted:) ### Error committing transaction. Cause: org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: org.apache.ibatis.executor.loader.ResultLoaderRegistry$LoadPair On Thu, Jan 14, 2010 at 2:44 PM, Clinton Begin <clinton.be...@gmail.com>wrote: > By nested results, yes, I mean collections and associations. And by > "flattening" I mean avoiding the use of those. > > iBATIS exhibits this behavior, the same way any ORM would, because the > object instances need to be cached to preserve object identity. So as > you're result set is being read through, each unique object is stored. > iBATIS isn't quite as effcient as something like Hibernate can be with > circular references though, in that depending on how you map it out, you may > end up with multiple instances of the same data (parent/child relationships > mapped with resultMap). > > So with iBATIS, the most memory efficient approach is to use nested select > associations/collections. But for query performance, nested resultMaps are > ideal. I often find I need to use a combination of both to get the best > optimization. But if I often don't load lists of complete objects either. > If I'm loading a large list, I'll use a lighter weight representation, and > then only load the complete object graph for individual instances. I've > never found a case where this wasn't a good idea anyway. Even when working > with something like Rails, a rich domain ORM, I would often write optimized > lightweight queries for large lists of flatter objects. > > The memory should not be significantly more than will ultimately be > required to store your final result set. And any additional memory used > should be released upon the closing of the SqlSession. > > If the memory isn't being released at the end of the session, that's a > different story... but otherwise, this is normal behavior. > > Clinton > > > On Thu, Jan 14, 2010 at 11:20 AM, Dave Rafkind <dave.rafk...@gmail.com>wrote: > >> Thanks for the reply. What do you mean by nested result maps or selects? >> Do you mean collections or associations with their own selects and result >> maps? Why would ibatis exhibit this behavior in that case? >> >> And by flattening, you mean the same kind of stuff used to avoid the n+1 >> select problem? >> >> On Thu, Jan 14, 2010 at 1:02 PM, Clinton Begin >> <clinton.be...@gmail.com>wrote: >> >>> If it uses nested result maps or nested selects, I'm afraid you're out >>> of luck. You'll need to reduce the query results, or flatten out the >>> results. >>> >>> Clinton >>> >>> On 2010-01-14, Dave Rafkind <dave.rafk...@gmail.com> wrote: >>> > Hi ibatis list, I'm new to ibatis so perhaps this is a noob question. >>> I'm >>> > using Ibatis 3 (ibatis-3-core-3.0.0.216.jar) with a somewhat >>> complicated >>> > schema (plenty of circular links etc). >>> > >>> > I'm doing something like this: >>> > >>> > List<MyIdObject> ids = session.selectList("getAll"); >>> > >>> > for (id : ids) { >>> > MyObject o = session.select("getOne", id.getActualId()); >>> > } >>> > >>> > The first query returns a list about 2k big, and the second query in >>> the for >>> > loop returns objects that are somewhat large (have several collections >>> in >>> > them, a discriminator, etc). >>> > >>> > The problem I have is that as the for loop marches on it uses an >>> > ever-increasing amount of memory. I would assuming that when the >>> objects in >>> > the body of the for loop go out of scope they can get garbage >>> collected, but >>> > apparently that never happens; is there some weird interaction with the >>> > "first-level cache"? Should I be going about this a different way? >>> > >>> > Thanks! >>> > Dave >>> > >>> >>> -- >>> Sent from my mobile device >>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: user-java-unsubscr...@ibatis.apache.org >>> For additional commands, e-mail: user-java-h...@ibatis.apache.org >>> >>> >> >