I have a question on DDD & Spring. I always design my application around anemic domain model and service taking care of business logic/persistence.
Assume you have a spring managed persistence/respository service for a Domain object e.g. Book. If I have to expose a save() method on book then i will need repository bean inside my domain or i will have to look up the context for the repository bean. Which is exactly opposite of Dependency Injection.
Now, If I have repository id injected into domain and domain object is cached ( clustered cache) and then on deserialization it will not have the injected repository service as spring containers will be different.
I might be wrong but if someone can explain me how this scenario will work, it would be of great help
I think that the "facade" of your application should use a Repository (or other infrastructure service) to save the "book". The book should not save it-self, this is responsibility of the Repository.
If you need to make any infrastructure operation (for example, search the database) from a Domain Entity, then you should gain access to this Repository by looking up the context (and getting coupled to Spring as a result) or injecting the Repository through Dependency Injection in the Entity.
The problem is that the "instantiation" of the Entity is not responsibility of Spring but of the Persistence Provider, so Spring cannot handle this injection. What to do?
Well, there are several ways (none of them very "beautyful") to do this:
Through AOP: you can instrument the code with Aspect Oriented Framework (like AspectJ) configuring the system to inject whatever dependency in the Entity in the instantiation moment.
Through a Hibernate interceptor: if your Persistence Provider is Hibernate, it offers you a hook to place interceptors in certain points of the life cycle of the Entities. You can configure an interceptor that looks-up the spring context to inject dependencies in the instantiation of every Entity.
Maybe the easiest way is to implement a little and static "serviceLocator" coupled with spring that looks-up services asked by the Entities when they need them. This service locator is just a layer to avoid your entities to get coupled to Spring.
I think that a "save" method (save in a DB, in example) doesn't belong to the domain object... Does the book "save" itself? Or is the repository saving it?...
Related
I have been working with Spring Data JPA repository in my project for some time and I know the below points:
In the repository interfaces, we can add the methods like findByCustomerNameAndPhone() (assuming customerName and phone are fields in the domain object).
Then, Spring provides the implementation by implementing the above repository interface methods at runtime (during the application run).
I am interested on how this has been coded and I have looked at the Spring JPA source code & APIs, but I could not find answers to the questions below:
How is the repository implementation class generated at runtime & methods being implemented and injected?
Does Spring Data JPA use CGlib or any bytecode manipulation libraries to implement the methods and inject dynamically?
Could you please help with the above queries and also provide any supported documentation ?
First of all, there's no code generation going on, which means: no CGLib, no byte-code generation at all. The fundamental approach is that a JDK proxy instance is created programmatically using Spring's ProxyFactory API to back the interface and a MethodInterceptor intercepts all calls to the instance and routes the method into the appropriate places:
If the repository has been initialized with a custom implementation part (see that part of the reference documentation for details), and the method invoked is implemented in that class, the call is routed there.
If the method is a query method (see DefaultRepositoryInformation for how that is determined), the store specific query execution mechanism kicks in and executes the query determined to be executed for that method at startup. For that a resolution mechanism is in place that tries to identify explicitly declared queries in various places (using #Query on the method, JPA named queries) eventually falling back to query derivation from the method name. For the query mechanism detection, see JpaQueryLookupStrategy. The parsing logic for the query derivation can be found in PartTree. The store specific translation into an actual query can be seen e.g. in JpaQueryCreator.
If none of the above apply the method executed has to be one implemented by a store-specific repository base class (SimpleJpaRepository in case of JPA) and the call is routed into an instance of that.
The method interceptor implementing that routing logic is QueryExecutorMethodInterceptor, the high level routing logic can be found here.
The creation of those proxies is encapsulated into a standard Java based Factory pattern implementation. The high-level proxy creation can be found in RepositoryFactorySupport. The store-specific implementations then add the necessary infrastructure components so that for JPA you can go ahead and just write code like this:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
The reason I mention that explicitly is that it should become clear that, in its core, nothing of that code requires a Spring container to run in the first place. It needs Spring as a library on the classpath (because we prefer to not reinvent the wheel), but is container agnostic in general.
To ease the integration with DI containers we've of course then built integration with Spring Java configuration, an XML namespace, but also a CDI extension, so that Spring Data can be used in plain CDI scenarios.
I'm working on a project Spring Boot project where there are two separate packages named domain and persistence.
The domain package primarily contains the Domain Classes (designed based on the business requirements) whereas the persistence package contains the repository interfaces defined by extending the repositories provided by Spring Data.
I have used Spring Data JPA annotations inside the domain classes and those classes are directly used when defining the repository interfaces as well. Everything works well here.
But the issues I have is that one could argue that domain classes do not need to know about the persistence implementation and domain classes should kept clean without polluting with Spring Data JPA annotation. This makes me this that I should maybe use a different set of classes (let's say Entity classes with more or less attributes) to implement the persistence so that I can keep the domain classes clean. But if I do this;
Spring Data repositories are going to work with these Entity Classes and I will not be able to use the interface based repositories out of the box since I will always have to map the Entity objects returned by repositories to Domain Classes.
I believe that at some point, I will introduce DTOs as well and when I reach this level, there will be too many mappings (Entity Classes to Domain Classes and then Domain Classes to DTOs). I personally think this mapping will be an overhead in the long run.
Summary -
Should I maintain Domain Model Classes and Entity Classes separately or should I just use Domain Model Classes along with Spring Data JPA annotations and KISS?
I think it is a mistake to separate the repository interfaces from the domain classes. Repositories are a part of the domain. Their implementation isn't, but you are not dealing with the implementation since that is provided by Spring Data (and JPA).
If your domain classes and your entity classes should be separate things depends on if they have different needs.
You might encounter scenarios where you need to model entity classes to accommodate the limitations of JPA or whatever persistence technology you use and you don't want to leak that into you domain.
But until you encounter that I don't see the need to separate them.
If you are concerned about annotations on your entities, it might help to realise that annotations are an extremely weak dependency. You can use your entities without the annotations even on the class path. So from a purist point of view they are a smell, but in reality I still have to find a situation where they are problematic.
If you really want to get rid of them you might want to look into jMolecules, which offer technology agnostic annotations for DDD concepts that then get translated into JPA annotations or whatever you want to use.
Suppose I've a bunch of microservices, each written on SpringBoot MVC (REST, Controller, Service, etc..)
Can anybody explain what is DDD's Aggregate in SpringBoot MVC? is it a controller? Or is it a specific microservice which is a root for some other microservices?
In other words, is aggregate something within a service with a controller's endpoint as a root? or is aggregate a sub-set of microservices with a particular SpringBoot application/service as an entry point to them?
It is neither a controller nor specific microservice.
It is a cluster of the domain objects that can be treated as a single unit (e.g. Order and its order line) (see this) which is retrieved , saved and searched by the repository.
The spring framework also provides an more specialised #Component called #Repository to represent the repository concepts (quoted from its javadoc) :
Indicates that an annotated class is a "Repository", originally
defined by Domain-Driven Design (Evans, 2003) as "a mechanism for
encapsulating storage, retrieval, and search behavior which emulates a
collection of objects".
Teams implementing traditional Java EE
patterns such as "Data Access Object" may also apply this stereotype
to DAO classes, though care should be taken to understand the
distinction between Data Access Object and DDD-style repositories
before doing so. This annotation is a general-purpose stereotype and
individual teams may narrow their semantics and use as appropriate.
As we use repository to save JPA #Entity or MongoDB #Document to the underlying datastore , so DDD aggregate is more align to them
Two things here.
Spring MVC is a boundary layer to translate between HTTP and internals of the app. The internals are where all the DDD happens, not the boundary itself
Spring Boot is for bootstrapping an application with all the common tools and making a runnable deployment unit.
So, in case of DDD an HTTP request comes to Spring MVC layer, there a domain request is instantiated and passed to domain core for execution. Domain response then comes back and is translated into HTTP response by Spring MVC layer.
I have just started learning Java Spring and the concept of Dependency Injection (DI) and Inversion of Control (IoC).
I learned that all objects whether it is singleton, prototype or request and sessions, are all retrieved from the container.
The container manages the dependencies between classes and the lifecycle/scope of the object.
The fundamental idea behind this is there are no "new" operators for application using Spring Framework as the backbone of the system. (Please correct me if I am wrong).
I wanted to modernize legacy applications coded without the Spring framework and manages the 3rd party libraries classes and injects them using Spring.
How should I approach this?
I learned that all objects whether it is singleton, prototype or request and sessions, are all retrieved from the container.
That is not quite right. Not all objects, but those you have the cotainer told to resolve, are retrieved from the container. In general you use the #Component annotation to mark which of your objects should the container know of. Besides #Component there are other annotations which do in principle the same, but allow a more finegrained semantics, e.g. #Repository annotation, which is at its base #Component and put #Target, #Retention, #Documented on top.
The container manages the dependencies between classes and the lifecycle/scope of the object.
Yes. The container does the wiring up for you, i.e. resolving dependencies annotated with #Ressource, #Autowired or #Inject depending on which annotation you prefer.
During the lifecycle there are possible events, which allow usage of lifecycle callbacks.
Also: You could determine the bean scope.
The fundamental idea behind this is there are no "new" operators for application using Spring Framework as the backbone of the system. (Please correct me if I am wrong).
The fundamental principle is, that you delegate the creation of objects of a certain kind to the container. Separation of creation and consumption of objects allows greater flexibility and in consequence better testability of your application.
Besides the "components" of your application, there are e.g. the typical containers like ArrayList or HashMap, upon which you use the new-operator as before.
I wanted to modernize legacy applications coded without the Spring framework and manages the 3rd party libraries classes and injects them using Spring.
How should I approach this?
From what was said above, it should be "simple":
1) Go through each class file and look for its dependencies
2) Refactor those out and put #Component on top of the class
Special case: 3rd party objects, where you do not have access to the source. Then you have to wrap its construction yourself into a factory e.g. with #Bean.
3) Add the missing dependencies via #Autowired (the spring specific annotation for marking dependencies)
4) Refactor components of the service layer with #Service annotationinstead of #Component.
5) Refactor the data access layer, instead of using #Component, you can use #Repository.
This should give you a base to work with.
we are using EJB3 in our application. Our design aim is to separate persistence layer from Business Layer. So we have developed XXXbean classes to be used as SLSB and XXXRepository classes to be used as persistence classes. We also have POJO that implement reusable NON business logic(get list of countries etc) and we call then service/helper Classes.
We use EJB3 JPA (using Hibernate provider) and Repository classes has all the methods for CRUD operation and the get methods for data access. Currently XXXRepository classes are all POJO and we instantiate these classes directly from the bean XXXClasses or from the service Objects.
Should the XXXRepository classes be SLSB ? what would be the benefits and pitfalls of converting them to SLSB?
An EJB is a container managed bean. This means, that the container manages a lot of options like the transaction, security, resource access (e.g. database) and offers possibilities like timers, remote access or interceptors. Another advantage is the pool and the reuse of instances.
I would say, that if you need something from this container managed options like an entity manager, then use an EJB, in your case an SLSB. But if you don't need any of the provided features, then a usual POJO will do that job.
If the XXXRepository classes are no SLSB, how do they access to the database to perform the CRUD operations? Are you using the Hibernate Session directly? How are the transactions managed? It may make sense to transform thes classes in SLSB and use the injected entity manager for this case.
Adam Bien has written a book called Real World Java EE Pattern. In this book he writes about good EJB architectures and also mentions, which classes should be an EJB (for example a ServiceFacade as a transaction boundary) and which classes can be used as POJOs.