15 Tips on JPA Rich Domain Modelling - Thinking In Objects - Not Mappings [For Greenfields]
- Forget about JPA, JDBC & CO for a moment.
- Try to identify concepts and abstractions from the target domain. Use them as candidates for entities.
- Reuse directly the names. Do not obfuscate them with additional technical naming conventions like XYZEntity or "BOs".
- Forget the database mapping and concentrate on good, DRY OO-design and fluent naming.
- Build objects, not structs - put logic into the entities if necessary.
- Forget getters / setters. Think about builders.
- Write unit tests for the business logic and run them, without involving the EntityManager etc. [optional - only if your logic in the entities becomes complex]
- Let the tool (JPA-provider) generate the DDL and the database layout.
- Write unit tests, without mocking out the database, early.
- Provide a lean facade/service layer (the easiest possibility are EJB 3 right now). It should only contain crosscutting concerns.
- Run load and stress tests.
- Import the database into an ER-Tool - optimize the DDL.
- Align the JPA-annotation, if needed.
- Provide orm.xml if required (you should have good reasons for it).
- Go to 11.
[Rich and anemic domain objects are discussed in-depth in the "Real World Java EE Patterns" book. See e.g. page 83 and 259]
9 -> do you mean tests that hit the database? (effectively beeing integration tests?)
Where do tests that actually do mock the database fit in? Or do they not make sense at all in your opinion?
What do you think about using an inmemory database for unit/integration-tests?
12 -> What is an OR-Tool?
Posted by Jonas on January 28, 2009 at 03:02 PM CET #
9 -> yes - just to test the mappings and syntactical correctness of the
I actually do not mock the database out, I build the objects in memory and test
the business logic directly. For more sophisticated tests I'm using Derby or
HSQLDB. In my last project I used Oracle XE image for testing. It really
depends on the project.
12 -> Sorry - > I meant ER like Erwin or ER-Designer,
Posted by Adam Bien on January 28, 2009 at 08:13 PM CET #
I enjoyed your post and especially point 11 caught my attention.
Given that you emphasize load and stress testing,
could give some basic scenarios / guidelines how you would perform it?
Also, what tools would you use to implement your tests?
Posted by Juha on January 29, 2009 at 09:53 AM CET #
the simplest possible way is:
1. Inject the EJB 3 facade into a Servlet, or JSR-311 resource class.
2. Use JMeter to generate the load - for simplicity just GET-requests (you should be aware of the REST folks doing so :-))
3. Use VisualVM to monitor your system.
thank you for your nice comment,
Posted by Adam Bien on January 29, 2009 at 10:33 AM CET #
What about applying the design patterns inside domain objects?
For example is it OK to implement State pattern in domain object (with transition logic in states) instead of using state codes (enums, static fields).
Posted by Miroslav on January 29, 2009 at 06:27 PM CET #
sure - why not? I always ask my self: "What happens in worst case?". ...and in worst case you will have to move the code somewhere else. But you should start with the simplest possible solution...
Posted by Adam Bien on January 29, 2009 at 06:30 PM CET #
I fear that you oversimplified Steps 1 and 4 a bit in that you forgot to mention some restrictions.
After going through steps 1 to 6, I now have a proper Java SE OO-implementation, but I am screwed as I cannot convert it to JPA.
First, I put great effort into making every class truly immutable (see Item 15 from Effective Java by Bloch), which includes preventing inheritance from outside the package. I did that in order to manually implement a concept which is already provided by the JPA with the @Version annotation. Well, now that I have discovered @Version, I can simply remove all defensive copies and publicize the constructors, etc.
Secondly, I implemented lots and lots and lots of generic classes and then some more. Now I have discovered that generic classes cannot be converted to Entities. This practically means, that I can start all over again.
Do you have a recipe for converting a well modeled OO-implementation derived by applying steps 1 to 6 into a JPA model, if there are lots of generic classes?
Thanks a lot!
Posted by mikem on March 18, 2009 at 01:55 PM CET #
Sorry to wake up this 2y-old post, but I wonder how you manage versionning and updates on your model in a long term project ?
I mean for example that when you are adding fields to a JPA entity, you need the DDL generated to contain ALTER and not CREATE statements.
Is it possible with main JPA implementations like EclipseLink or Hibernate ?
Posted by jlamande on January 05, 2012 at 04:23 PM CET #