I'm having a hard time understanding the Repository Pattern.
There are a lot of opinions on that topic like in Repository pattern done right but also other stuff like Repository is the new Singleton or again like in Don't use DAO use Repository or just take Spring JPA Data + Hibernate + MySQL + MAVEN where somehow a Repository appears to be the same as a DAO object.
I'm getting tired of reading this stuff since imho this can't be such a hard thing as it is displayed in a lot of articles.
I see it like this: It appears that what I want is something like this:
------------------------------------------------------------------------ | Server | ------------------------------------------------------------------------ | | | | Client <-|-> Service Layer <-|-> Repository Layer <-|-> ORM / Database Layer | | | | | ------------------------------------------------------------------------
The Service Layer
takes *DTO
objects and passes those to the Repository Layer
that basically is nothing more than "the guy" who knows how an entity can be stored.
For example assume you have a composition of some tools (please note that this is just pseudo code)
@Entity class ToolSet { @Id public Long id; @OneToOne public Tool tool1; @OneToOne public Tool tool2; } @Entity class Tool { @Id public Long id; @OneToMany public ToolDescription toolDescription; } @Entity class ToolDescription { @Id public Long id; @NotNull @OneToOne public Language language public String name; public String details; }
The thing I'm not getting is the part where I am getting a ToolSetDTO
object from the client.
As I understood it so far I could write a ToolSetRepository
with a method ToolSetRepository.save(ToolSetDTO toolSetDto)
that "knows how to store" a ToolSetDTO
. But almost every tutorial does not pass the *DTO
but the Entity
instead.
What's bothering me here is that if you take my ToolSet
example from above I'd have to do the following steps:
toolSetDto
and check if not null
tool*Dto
owned by toolSetDto
DTO
to Entity
otherwise create a new database entry toolDescriptionDto
and convert/save it to the database or create a new entryToolSet
(entity) and set it up for persisting it in the databaseAll this is too complex to simply let the service function (interface for the client) handle this.
What I was thinking about was creating e.g. a ToolSetRepository
but the question here is
ToolSet
entity object or does it use a DTO
object?*Repository
allowed to use other repository objects? Like when I want to save ToolSet
but I have to store Tool
and ToolDescription
first - would I use ToolRepository
and ToolDescriptionRepository
inside ToolSetRepository
? *Repository
classes due to dependency reasons. I don't know why I can't get my head around this. It does not sound that complicated but there's still help out there like Spring Data
. Another thing that is bothering me since I really don't see how this makes anything easier. Especially since I'm using Hibernate already - I don't see the benefit (but maybe that's another question).
So .. I know this is a long question but I put already a few days of research into it. There's already existing code I am working on right now that starts to become a mess because I just can't see through this pattern.
I hope somebody can give me a bigger picture than most of the articles and tutorials which do not get beyond implementing a very, very simple example of a Repository Pattern.
The idea behind the Repository pattern is to decouple the data access layer from the business access layer of the application so that the operations (such as adding, updating, deleting, and selecting items from the collection) is done through straightforward methods without dealing with database concerns such as ...
Repository Pattern is used to create an abstraction layer between data access layer and business logic layer of an application. Repository directly communicates with data access layer [DAL] and gets the data and provides it to business logic layer [BAL].
They decouple application and domain design from persistence technology, multiple database strategies, or even multiple data sources.
Benefits of Repository PatternIt centralizes data logic or business logic and service logic. It gives a substitution point for the unit tests. Provides a flexible architecture. If you want to modify the data access logic or business access logic, you don't need to change the repository logic.
You can read my "repository for dummies" post to understand the simple principle of the repository. I think your problem is that you're working with DTOs and in that scenario, you don't really use the repository pattern, you're using a DAO.
The main difference between a repository and a dao is that a repository returns only objects that are understood by the calling layer. Most of the time the repository is used by the business layer and thus, it returns business objects. A dao returns data which might or might not be a whole business object i.e the data isn't a valid business concept.
If your business objects are just data structures, it might be a hint you have a modeling problem i.e bad design. A repository makes more sense with 'rich' or at least properly encapsulated objects. If you're just loading/saving data structures probably you don't need a repository the orm is enough.
If you're dealing with business objects that are composed from other objects (an aggregate) and that object needs all its parts in order to be consistent (an aggregate root) then the repository pattern is the best solution because it will abstract all persistence details. Your app will just ask for a 'Product' and the repository will return it as a whole, regardless of how many tables or queries are required to restore the object.
Based on your code sample, you don't have 'real' business objects. You have data structures used by Hibernate. A business object is designed based on business concepts and use cases. The repository makes it possible for the BL not to care about how that object is persisted. In a way, a repository acts as a 'converter/mapper' between the object and the model that will be persisted. Basically the repo 'reduces' the objects to the required for persistence data.
A business object is not a ORM entity.It might be from a technical point of view, but from a design pov , one models business stuff the other models persistence stuff. In many cases these are not directly compatible.
The biggest mistake is to design your business object according to storage needs and mindset. And contrary to what many devs believe, an ORM purpose is not to persist business objects. Its purpose is to simulate a 'oop' database on top of a rdbms. The ORM mapping is between your db objects and tables, not between app objects (even less when dealing with business objects) and tables.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With