Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE. Founder and creator of http://computoser.com and http://welshare.com . Worked on Ericsson projects, Bulgarian e-government projects and large scale recruitment platforms. Member of the jury of the International Olympiad in Linguistics and the Program committee of the North American Computational Linguistics Olympiad. Bozhidar is a DZone MVB and is not an employee of DZone and has posted 81 posts at DZone. You can read more from them at their website. View Full User Profile

An idea for JPA regarding domain-driven design

09.06.2011
| 5924 views |
  • submit to reddit

JPA and domain-driven design don’t mix well. In fact, JPA “entities” are representatives of the anemic data model that Fowler warns against. I have already discussed DDD in the light of JPA and dependency injection, so I won’t go into much details here whether anemic data model is bad or not (for the record: I don’t think it’s bad).

But for the times you need to inject dependencies into entities standards don’t give you a hand. The only option is @Configurable, which requires aspectj weaving, which is “black magic” to me. So why you can’t inject dependencies into entities? Because they are created by you and not by a dependency injection framework.

Well, here’s a weird idea. What if JPA 3 had EntityManager.createEntity(Foo.class) so that your entities are managed all the time? Then you’ll be able to inject dependencies different than other entities (which is already handled by JPA through associations). How will it work?

  • JPA will require a DependencyManager which will provide the dependencies, handle their lifecycle, etc. CDI will be the default dependency manager of course, but any framework (spring, guice, etc) can plug-in their implementation
  • whenever you em.create(..) your entity it will have its dependencies set – as if the entity is created by your DI framework
  • this would mean that the “transient” state of entities will not exist (if you choose the create() method, that is)

But… detached entities, or the cases when you need to create the entities where you should not have access to the entity manager (in a controller for example) are the most important thing. And I can’t give a satisfactory suggestion to this one. You would either need to inject EntityCreator which, under the hood will either use the entity manager, or another mechanism (if you are likely to switch from JPA to something else). But this could be a “best practice” rather than a standard interface because if it is a JPA interface that’s still a direct dependency of the web layer on JPA. Another option is to propagate the creation through all layers, but that is boilerplate. A third option is to have detached entities automatically attached when they ‘enter’ the service layer (through AOP). And a downside to the idea is that people will be tempted to inject the EntityManager itself, which will violate layer boundaries. And another downside is that people may (rightfully) say – “what, I can’t use the new operator anymore?!”

So I’m just throwing an idea. I would be surprised if CDI and JPA designers didn’t think of something similar, so I’d like to hear some (more) cons.

 

From http://techblog.bozho.net/?p=368

Published at DZone with permission of Bozhidar Bozhanov, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Mladen Girazovski replied on Wed, 2011/09/07 - 1:27am

I don't see a problem with JPA and DDD at all, I have used it that way already.

I agree that most tutorials and examples use an anemic domain model, but that is not the only way to go with JPA or ORM in general.

Also, i do not understand what you are trying to accomplish with an EntityManager.createEntity(Foo.class) method, DDD suggests using explicit factories, and thats what you're supposed to use if you're doing things the DDD way.
The specific factory for a specific Entity assigns the ID, which independant from the fact if its a transient or already persited Entity, no need to avoid the transient state, which would have other implications (having to persist entities even if they are discarded because the user canceled the operation).

All in all i do not see any problems using DDD with ORM in general, be it JDO or JPA, or a conrete ORM like Hibernate or EclipseLink, the DDD way is sufficient for ORM and vice versa.
However, the ORM is not supposed to solve every of your problems, it is just about persistence.

Fabrizio Giudici replied on Wed, 2011/09/07 - 4:03am

AspectJ weaving is no more black magic than bytecode manipulation routinely performed by JPA implementations such as Hibernate, TopLink, EclipseLink, etc... What's the problem?

Bozhidar Bozhanov replied on Wed, 2011/09/07 - 4:32am in response to: Mladen Girazovski

DDD with ORM + dependency injection is problematic, because you can't have the DI framework inject your dependencies into the domain objects.

Bozhidar Bozhanov replied on Wed, 2011/09/07 - 4:40am in response to: Fabrizio Giudici

They use dynamic proxies, which is still an OOP approach, although, for concrete classes, there's no good support in the language and its libraries. Btw, in normal (eager) scenarios JPA implementations don't need to make proxies.

I called it "black magic", because the dependency appears to come from nowhere. With JPA proxies you get that from the entitymanager, so even though it may look strange, it is obvious where it comes from. With aspectj you have "new Foo()", and suddenly your instances has all sorts of things happening to it - contrary to what you'd expect from a normal object. 

I agree that aspectj is not a bad thing, but note also my point that it is only supported by spring. I was suggesting something more standard.

Mladen Girazovski replied on Wed, 2011/09/07 - 4:59am in response to: Bozhidar Bozhanov

With Guice you could, but there is no need for that if you're using a factory, right?

Since that is something that a factory is very well suited for, if not that is one of the main reasons for factories, taking care of complex stuff during object creation and returning the created instance ;)

DDD relies on the concept of explicit factories in the Domain Model, while most DI frameworks suggest to make the factories part of the infrastructure, DI frameworks are not documented with DDD in focus, but can be used for DDD, but of course not if you follow a non-DDD approach. <br>

Once you've made them part of your domain model, they can be used even from entities or domain services.

Again, there is nothing holding you back from using (DI/ORM) Frameworks in a DDD manner.

(Note: When i say Entity, i mean DDD Entities, not necessarily JPA Entities). 

 

If you're reffering to retreval, deletion and editing of existing objects, you wouldn't use a factory for that, but instead a repository, only there the Entitymanager is used in case of JPA.

Jan Friderici replied on Wed, 2011/09/07 - 5:05am

I agree with Fabrizio. There is now magic (neither black nor white) in AspectJ. If you put an "@Configurable" before your class you know that it will get it's dependencies injected by spring. If you use compile time weaving things are clearer then the byte code weaving done be jpa and friends.

Fabrizio Giudici replied on Wed, 2011/09/07 - 8:31am

I called it "black magic", because the dependency appears to come from nowhere. With JPA proxies you get that from the entitymanager, so even though it may look strange, it is obvious where it comes from.

Generally speaking I agree that everybody should only use stuff that he's comfortable with, but it's always worth while to make a rational check of our feelings. The dependency doesn't "come from nowhere": it just comes out of the @Configurable contract. It's just like the EntityManager of JPA being injected out of the @PersistenceContext, or any other stuff injected because of an annotation. All contracts declared by an annotation and enforced by a container. None of those objects is a "normal" object in the sense you're referring to.

True, Spring is not a "standard", in the sense that there's no specification etc... So what? I'd only be worried if it was an obscure product made by an unknown community... which is not the case.

Given that, people are of course free of choosing not to use Spring and stay with JEE, which brings us back to your point, where you're proposing JPA enhancements. GIven that Spring and JEE cross-pollinated a lot in the past, I don't understand why to reinvent the wheel with unneeded complexity, given that the @Configurable approach works. A single annotation on the class is enough for a contract that specifies that @Inject must be enforced also for JPA entities. For the implementation, if one doesn't want to depend on AspectJ, the thing could be made by an annotation processor, which is Java 6 standard.

Cloves Almeida replied on Wed, 2011/09/07 - 8:41pm

I, in fact, like the anemic model better. Like Evans said, an entity is not about it's attributes - it doesn't matter if you split it into two classes.

You could be done with a "Product" as JPA entity and "ProductBean" being a CDI bean. The only issue is that you need two files instead of one, and need to pass the entity instance as method argument. IMO a small price to pay.

Also, keeping your entity action/injection free allows you to reuse the domain classes outside the container - in an standalone android app, for instance.

John David replied on Thu, 2012/01/26 - 3:21am

I’m not quite understanding the issues you see with “detached entities in the contoller layer”? I presume the case is you create an entity there (using DI) and then want to persist it?

Java Eclipse

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.