Web frameworks seem to always wander away from good OO code (Where you group code and data together in an object, think in terms of sending messages to that object, etc)
The main problem seems to be the existence of the bean pattern. You use a bean pattern (often called POJOs these days because people don't seem to understand the difference) to interact with the database, web services and most other things.
So no you are stuck with this ball of setters and getters with no code--so you tend to add a bunch of--well essentially static functions to manipulate these things. Nearly all the advantages of OO code are gone.
I see three solutions I'm considering, but wanted to hear if there were any serious disadvantages to any of them.
1) use a POJO pattern instead of a bean pattern. This would mean eliminating setters and getters from your POJOs (so you can have encapsulation/data safety) and instead adding business logic methods. This seems to make the most sense--in fact I think it's why libraries like hibernate switched away from requiring Beans to allowing POJOs, yet everyone still seems to use a bean pattern instead.
2) extend your Bean with a business logic class that uses the bean's fields as storage. This seems flakey and problematic, but would be very easy to drop into an existing codebase as a way to migrate...
3) Wrap a Bean pattern object with a business-logic object. Mostly I think this might be necessary if #1 is really problematic.
What I'm mostly wondering is why I've never seen #1 used. I'd really love to hear from anyone who used the Pojo pattern (With business logic and without setters and getters) for hibernate objects and had problems with it (or had it work really well)...
There are good reasons to keep (most of) business logic outside the data objects, but optimal design will include certain parts of it there. This is not exactly easy to get right, especially in a blue-collar team setting, which is I guess 95% of all Java dev teams out there.
I like to put some simple, self-contained, widely reusable pieces of logic into my data objects; code that is inherently coupled to that data without regard to any specific business request. Examples would be some conversions, validations, etc.
As far as getters and setters, I avoid them at all costs. You could use public final fields, or just plain public fields. The getter+setter combo gives you exactly as much encapsulation as a public field: zero.
As far as ORM solutions, I use Hibernate strictly as a convenience over SQL, and never as a persistent state manager. The mapped classes are there only as a replacement for XML mapping; they are never even instantiated in read operations. For inserts I save each object individually, which maps one-to-one with a single database row, without transitive persistence. This basically means that my Hibernate model objects are just a Java way of looking at database rows (plus the convenient join column specifications—HQL looks much nicer without those redundant join criteria).