My team decided to try DDD approach in new app we're developing now.
One of the obstacles that we face is our platform - we are forced to use ActiveObjects ORM framework (https://developer.atlassian.com/display/DOCS/Getting+Started+with+Active+Objects).
Given that DDD is huge topic by itself, existence of such a constraint makes things more complex. The main problem is propagation of changes of Domain Model entity attributes to the persistence storage via ActiveObjects. Are there any good solutions we can consider?
ORM is a persistence detail i.e totally unrelated to the Domain (different layers). DDD is not a huge topic. It's a simple mindset, tricky to understand and very skill dependent to implement (it's not a "how to" methodology).
DDD uses Repositories for everything persistence related. The Domain only sees the repositories (abstractions only), never the db, orm etc. The ORM is used by the repository. A properly encapsulated domain object might not be easily mappable to an ORM and you'll need different approaches for those cases (the memento pattern is a clean but expensive - boring - to maintain solution). But the essence is that Domain doesn't know about ORM and the Repository is responsible for persisting/retrieving domain objects (using the ORM).
You should also employ CQRS, you don't want your business objects designed for UI or reporting queries.
Related
JHipster is great. It, however, models all objects as domain entity objects. An enum class, for example, is treated as a domain class. If I want to practice the domain driven design, I need to convert some of entity classes, which are generated by JHipster, to value classes along with other types of changes such as replacing primitive types with domain object data types. Can I still run import-jdl after making such changes? In the other words, whether the changes are maintiable with a JDL?
BTW, there is a good talk on DDD by Edson Yanaga posted on youtube.
An interesting talk about DDD:
Implementing DDD with the Spring Ecosystem by Michael Plöd # Spring I/O 2018
There's a concept coming from the video, that I've found very important:
JPA entities are not domain entities.
JPA entities and repositories are what you use to persist data on the Db. While the Domain is what you use inside the application.
To answer, I think that you can build your domain classes separately, without caring too much about JPA entities. I suppose that's better to have a consolidated JPA layer before to start building the Domain side, if the two are somehow linked (and usually they are)
Please consider that I've just started to study this topic. Would be good to hear other opinions.
It's a pity that, in short, JHipster just does not support Value Objects, which makes it incomplete to design a DDD application by only caring about models.
See
issue1,issue2,another SO question
I am learning Spring Data JPA, and I came across the term "JPA repository" (to be specific Spring Data JPA repository). I want to understand if the term "JPA repository" is a general concept (like JPA - a standard specification) or coined by Spring Data project?
What exactly does "repository" in this context means?
What exactly does "repository" in this context means?
Repository is one of the patterns introduced in Patterns of Enterprise Application Architecture (Martin Fowler, 2002). In the book, Repository defined as:
Mediates between the domain and data mapping layers using a
collection-like interface for accessing domain objects
A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper, that isolates domain
objects from details of the database access code. In such systems it
can be worthwhile to build another layer of abstraction over the
mapping layer where query construction code is concentrated. This
becomes more important when there are a large number of domain classes
or heavy querying. In these cases particularly, adding this layer
helps minimize duplicate query logic.
A Repository mediates between the domain and data mapping layers,
acting like an in-memory domain object collection. Client objects
construct query specifications declaratively and submit them to
Repository for satisfaction. Objects can be added to and removed from
the Repository, as they can from a simple collection of objects, and
the mapping code encapsulated by the Repository will carry out the
appropriate operations behind the scenes. Conceptually, a Repository
encapsulates the set of objects persisted in a data store and the
operations performed over them, providing a more object-oriented view
of the persistence layer. Repository also supports the objective of
achieving a clean separation and one-way dependency between the domain
and data mapping layers.
Further Reading
For more detailed discussion about Repository pattern, you should take a look at Patterns of Enterprise Application Architecture (Fowler, 2002) and Domain Driven Design (Evans, 2003).
I'm trying to wrap my head around JPA and have learned quite a bit. JPA is a java specification and providers implement this spec. I Understand that part.
What I don't understand is how Spring Data comes into the picture. Is Spring Data also a provider like Hibernate or OpenJPA? If not, what is it? How does Spring Data "make things easier"?
The Spring Data project in general is an umbrella project with the following mission statement:
… provide a familiar and consistent Spring-based programming model while retaining store-specific features and capabilities.
So we approach the persistence space in general not only relational data access through JPA. The important piece here is two fold:
Programming model instead of generic API
Support for store specific features
As the data access space is so diverse these days, trying to approach all of the stores with a single unifying API is doomed to fail. You'd end up with a least common denominator that hides away the store specific parts - in times where you selectively choose a particular store because of it's specifics. Abstracting those away totally subverts this. Especially trying to use JPA is wrong in our opinion as it's deeply tied to relational concepts (#Table, joins, transactions) by definition.
Still, you don't want to work with completely different APIs, don't wanna be lost in store differences if you work with multiple ones or switch from one project to another. Spring has traditionally helped in that regard by embracing a consistent programming model, that features abstractions that work the same way but are still specific to a particular technology. For example, JDBC and JMS are completely different technologies. Spring offers both a JdbcTemplate as well as a JmsTemplate that cover the same responsibilities (resource management and exception translation) and lower the learning curve when moving from working with JDBC to JMS or vice versa.
Spring Data picks up on that by exposing store-specific functionality through abstractions that Spring developers know. I already mentioned the template, but that also includes general configuration mechanisms (XML namespaces, using DI and AOP etc.).
Repositories
The very top layer of this programming model is the repository abstraction. In its core, it significantly simplifies the development of data access layers by letting you avoid to write more implementation code than strictly necessary. It provides CRUD functionality out of the box, pagination as well as declarative query methods.
Assume a Customer domain class. Enabling persistence for it is just a matter of declaring a repository interface like this:
interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
List<Customer> findByLastnameContaining(String lastname);
}
Now it's a matter of configuration (and domain class mapping) to be able to create an instance of this interface and use it from a client. PagingAndSortingRepository includes basic CRUD functionality as well as stuff like Page<Customer> findAll(Pageable pageable) (so page-by-page access). As you can see, we also support a query derivation mechanism to avoid needing to write any implementation code for simply queries. For more complex ones, we allow the manual declaration (e.g. using #Query on the method) or even the manual implementation if necessary.
A neat side-effect here is, that by a flip-switch in the configuration you could use the same repository interface to persist Customer instances into a MongoDB. That doesn't mean we recommend to blindly move from one store to another as the stores usually require the data model to be adapted to work efficiently. However it allows developers to quickly switch between projects working with different stores as the repositories just work the same way (implementing the programming model over common API approach).
JPA specifics
Spring Data JPA is actually a thin layer implementing the repository abstraction plus a few other bells and whistles. So we're not replacing persistence providers but actually leverage them through the API, even mitigating some of the quirks and differences between individual JPA providers.
Think of Spring Data as a way to support JPA and many other persistence models in a manner that is transparent to your own code. Spring Data makes it easier for you to manipulate more types of data source systems in a unified interface. Without Spring Data, you would need to introduce more adapters in your code, each time you would have to deal with extra logic.
spring-data JPA is not a JPA provider. It is a library / framework that adds an extra layer of abstraction on the top of our JPA provider(Hibernate/TopLink). If you are using Spring Data in your project, you are not going to write most of the low level data access operations like writing SQL query, DAO classes etc.
But you must have a JPA-Provider (Hibernate, Toplink etc) to implement spring-data-jpa.
I've been doing some reading lately and one thing that I've come across was this article about the Anaemic Domain Model from Martin Fowler. I know, it's old, but somehow very actual in Java world. So I'm trying to move towards a more domain-driven design. One option would be to go with the Active Record model. However, I don't really like the current implementation it has in Scala. It completely couples the domain objects with the persistence type (not so bad in most cases but I have a project where I need to store something both in a RDB and in Mongo). Then I ran across this article about Spring, Hibernate and Scala and though here too the domain object is coupled with the JPA trait, I noticed how he uses Spring to inject a Notification Service. Can't the same mechanism be used to inject a transparent DAO interface? Have you seen this used anywhere? Any thoughts on the idea?
You should have a look at Spring-Data, this project provides some kind of abstraction over different data storages.
If I'm developing a hiberante application, am I also developing a DD model?
My application does have a service layer ( which is in lines with the Observer pattern). Will there also be a Domain Layer wherein all the hibernate entities exist?
I'm looking my application somehting like this:
Do I need to know Domain Driven Design to write Hibernate Entities?
Can the application be hybrid - OOD in the service layer and DDD in the persistence layer?
I'm confused. Please clarify.
If I'm developing an Hibernate application, am I also developing a DD model?
When using Hibernate, you'll probably create a domain model of entities and do some domain modeling but you aren't necessarily following Domain-Driven Design principles, there is no direct implication. And actually, I'm tempted to say that it's most often the contrary, most Hibernate applications end up having an anemic domain model.
Do I need to know Domain Driven Design to write Hibernate Entities?
No. there is no particular knowledge to have to write Entities. However, if you want to follow DDD, you obviously need to have some knowledge of DDD. And if you want to go this direction, using Hibernate (as your factory for entities) has some implications on the implementation. Domain-Driven Design with Spring and Hibernate is a very nice blog post on the topic and describes an AOP based approach.
Resources
The official Domain-Driven Design Community website
The Domain-Driven Design yahoo group
Domain-Driven Design Quickly (great summary book of Eric Evans's reference book).
Chris Richardson's aop-ood sample application
See also
Still confused about repositories
actually DDD is an approach and is not tied to the tools that you are using.
you can use Hibernate or any other OR mappers to do DDD or any other aspects that you thins is suitable for your case.
read more about DDD:
http://en.wikipedia.org/wiki/Domain-driven_design