Collection mapping is one of those “hello world” problems. (The “hello world” example in the doco looks totally trivial and completely ideal [which is the problem], but suck-in-the-galaxy-greet-it-and-then-map-all-the-stars problem, which is more like what your real app looks like, is far less than trivial and not so easily achieved with the demonstrated toolkit). In my experience, collection mapping is the cause of all sorts of pain and performance perfidy.
Here’s a further situation where I find that they really get in the way. Consider integration with existing systems that use highly-normalised database schemas (designed by advanced SQL programmers who know what they are doing in that language).
This is not an uncommon scenario – we have this system ‘A’ which (let’s say) has all our customer shipping, product, warehousing data in it. We don’t want to replace it. But we need to extend it so that e.g. available to web systems. Or maybe it needs to be integrated into the big fancy off-the-shelf CRM we’re installing. Something like that. We need to build some sort of service layer around this system ‘A’ so that other systems can access its data and/or functions. It’s common to think that an ORM around that big complex database schema is going to help, but in my experience, it doesn’t for many of the reasons Stephan and Aldo list. That sort of highly-normal database schema in my experiences completely kills ORM object representations stone cold. You end up with so many LazyInitialisationExceptions and various other problems it sucks productivity out the developers and performance out of the system.
Also, I get a bit annoyed about ORM abstractions leaking into the web tier, this is especially prevalent with using annotations rather than ORM mapping files.
Different sorts of approaches are sometimes needed to be applied with careful thought in that scenario. Perhaps you need to model the “intermediate” domain you need directly, and then use, for example, simple DAO layers which operate directly on the domain you’ve defined. These DAO layers then might call functions (stored procs) in the database that do the problematic mapping in an efficent relational language (after all it’s the direct representation of the target data format).
I’m not saying that you have to do the above in every case, or that an ORM is always wrong, but anyway the point is, ORM isn’t a magic bullet like any other technology you have to consider carefully. Your application doesn’t always need one by default.