How To Treat The JPA EntityManager?
The structure of the JPA
EntityManager is surprisingly similar to the Domain Store Pattern. Strictly speaking
EntityManager is the realization of the Domain Store pattern.
The Domain Store pattern itself is an object oriented variation of the Data Access Object pattern. It could be even considered as "DAO 2.0". See also post DAO -- Reader's Questions.
Because the EntityManager already encapsulates the concrete ORM-implementation, as well as, the underlying database, there is no need for any further layer of indirection.
From the conceptual perspective the
EntityManager is a generic, out-of-the-box Control. Therefore there is no need for any further wrapping and you can inject the
EntityManager directly to the Boundary.
So, whats the difference between a regular Control and the EntityManager?
Methods of a typical Control are coarser, than EntityManager's methods. Naturally the interactions with EntityManager (particularly the construction of queries), can require a considerable amount of code. However this will result in a complex Boundary and lead to refactoring: the code of a bloated Boundary is going to be factored out anyway into Controls. At this place there is no difference between reducing the complexity of a Boundary caused by business code or caused by direct interaction with EntityManager and the construction of JPA QL queries. Simple CRUD operations still remain simple and do not require any refactoring.
J2EE design was based on top down principles, Java EE is rather "bottom up": you should refactor on demand and not upfront. Empty layers and wrappers were a best practice in the J2EE era, but are an anti-pattern now (Java EE 5/6/7/*).
[See also an in-depth discussion in the "Real World Java EE Patterns--Rethinking Best Practices" book (Second Iteration, "Green Book"), page 259 in chapter "Data Access Object", page 419 in chapter "Entity Control Boundary (ECB)—The Lean Way" and page 83 in chapter "Control"]
See you at Java EE Workshops at MUC Airport, particularly at the Java EE Architectures workshop!
I'll accept this as an adequate answer to my question to your previous post ("Bureaucratic design...) :0)
Posted by Rune Molin on October 21, 2013 at 01:49 PM CEST #
exactly! The answer was just too long, so I decided to write a post about that.
Thanks for the great comment and so the inspiration for this post.
Hopefully you are happy with the reasoning.
cheers && thanks!,
Posted by Adam Bien on October 21, 2013 at 08:54 PM CEST #
I agree with what you are saying here. However, I still struggle with the urge to have the EM wrapped in an abstraction layer. Perhaps this is a holdover from the layer driven development of the past.
The main reason I want to do it is b/c of the lack of type safety in named queries as well as the verbosity of having to call them. I also feel like their is some crosscutting logic surrounding the EM that would feel cumbersome repeated across the application. For instance, how do we handle logging around NamedQueries, or what do we do if a getSingleResult throw a NonUniqueResultException.
I have been toying lately with the idea of creating an annotation preprocessor that would generate Managers for domain objects containing methods from the NamedQueries listed on the object with parameters. At least then we would get a compile time error when a named query is invoked improperly. Obviously, this comes with the price of generating code, which is not an ideal solution (as Lombok is showing me now, keeping me stuck on NetBeans 7.3.1). Might be a fun thing to tinker with.
Thanks for the post. As you can see, it is something I have been thinking over for a while now.
Posted by Kerry Wilson on October 22, 2013 at 08:47 PM CEST #
I think AB's point is that you don't need to build up that abstraction upfront for most cases. I think named query logging can be enabled other ways (I'm pretty sure eg hibernate log's them anyway at some debug level)
Posted by Solerman Kaplon on October 24, 2013 at 09:43 PM CEST #