I am developing a spring restful application that uses hibernate. I am coming across scenarios where i had to place jackson json annotations on entity getters. Ex: One to Many mappings.
Is it a good idea to place jackson json annotations on hibernate entities? Or should i go with DTO pattern to pass data that is just needed by UI? I may end up creating a DTO for every entity.
Below is the application architecture. Common is at root level. DAO has dependency on Common and so on.
Common <- DAO <- Services <- Web
DAO has entities
Services or Web can have DTO's
Please let me know your thoughts or suggestions.
Disclaimer: I am speaking from opinion and experience here
Separate dto and entities are common practice. What you choose to do really depends on it's use. One of the drawbacks of adding DTO annotations on your data model entities is versioning. Versioning becomes hard when your data model is tied to your contract. If your webservice is only used by a consumer you own and its deploy schedule is the same then it's probably not worth separating dto/entities. If you don't need versioning and you mostly have CRUD web services then you may want to look into spring data rest.
If you arn't so lucky, and have multiple consumers, then you may want to think through a few version breaking changes and how you will handle it. This will help you see the value in separating the data and contract.
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 have the following scenario:
A JAX-RS Webservice that is responsable for the business logic and database interactions.
A webapp that will be used by the end users.
A webapp that will be used by administrators.
My problem is that I want to reuse the entities from the webservice on the other apps, but it is highly wrapped with frameworks like JPA, JAX-RS, CDI, among others... So I am having a hard time to isolate them. What I want is to know the best workaround and why should I use it instead of others.
Maybe DTO is the way to go (with support from some object mapper library like Dozer)
Please take a look at following article for more details: http://zezutom.blogspot.com/2012/02/thoughts-on-data-transfer-objects.html
Write you entity objects as Plain Old Java Objects (POJOs), with proper constructors, setters, etc. Apply the annotations that allow the JPA to persist them and do the object to relational mapping in such a way that, if those annotations were all stripped away you could still create and manipulate those objects fully, using the public methods of the class. It can be helpful if you create the POJO first, then add the annotations afterwards.
As the POJOs stand alone they are not at all part of your repository layer. You can use them without using the JPA at all.
I'm developing a web application with Spring MVC, Spring Data JPA and Hibernate, the data access part is taken care of by the repositories provided by Data JPA
However, I'm planning to have a generic service layer (atleast for the common operations), is it a good practise? Or is it advised to not generalise it?
If part of you application will consist of repeating same actions on different objects, it can make sense to have a generic abstract parent class for common operations.
You will have to decide if the gain in de-duplication of code is worth the complexity of the generic. There is no general rule ...
If your app is simple (mostly CRUD) operations then you can access your Repository classes directly.
If you have additional server-side business logic that needs to be applied to data or if you need to orchestrate multiple data access calls together then adding a Service layer would be appropriate.
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.
In a complete Java EE application that's clustered is the DTO pattern still a valid option? The application in question uses EJBs Hibernate and Struts with Spring etc. Is there anything wrong with transferring domain objects in such a scenario?
EDIT: Just to clarify my question, with modern day resources and improvements in Java EE is there a reason not to just use domain objects? If there is not then isn't DTO pattern sort of fading out and shouldn't be used in new applications?
Is not deprecated. It depends on the application architecture if the DTO pattern should be used or not. For example, when you develop Web Services (using JAX-WS or JAX-RS), you should send DTO's over your web methods so a C# or Python client application may consume it, and your web method should not return an object which class has Hibernate annotations, remember than in other languages the Entity won´t be created with those annotations or other business logic inside.
EDIT (Based in your comment): That depends on the software architecture. For example, I'm working on a SOA project and we use DTO's for the Services Layer and the Presentation Layer. More deeper inside, we even use DTO's to handle database communication inside the services, we use only SP's to communicate with DB, so no Hibernate or any other ORM tools can work there, we could use Spring DAO and that framework uses DTO's too. You can find lots of DTO pattern in many applications nowadays.
More info that would be great for this question:
Difference between DTO, VO, POJO, JavaBeans? (where basically, any DTO is a POJO).
Core J2EE Patterns - Transfer Object
EDIT 2: Another source of information that will explain the main reason for using DTO's design, explained by Martin Fowler
LocalDTO
Conclusion: DTO's are not an anti pattern. DTO's are meant to be used only when you need to pass data from one subsystem to another and they don't have a default or standar way to communicate.
It is a very useful pattern in Java EE.
I use a DTO to transfer related entity objects from EJB beans to the UI layer. The entity objects are fetched from DB in one transaction (see TransactionAttributeType.REQUIRED) and stored in the DTO object. The DTO is consumed in the UI layer.
A pattern is pure design. There is no "deprecation" of pattern, but less usage over time (or over-usage).
Personally, I don't see why not to use DTOs.
For example - at oVirt open source project we have entities representing business logic entities in the domain of Virtualization.
These entities should be either annotated by Hibernate annotations (actually, they are today, as we started working on hibernate POCs) and serve as the DTOs , and then have clean from annotations objects that will mapped to them (let's say, using dozer framework) and used by client
(I don't like have at client side code with unnecessary annotations), or the entities should serve as the client objects (value objects) passed to the client and we should have other classes serve as the DTO entities
The minus in the above approach is that you might have 2 parallel class diagrams - one for DTOs and one for value objects (that are used by clients) - but , in many cases in design , there is a trade-off.
You must understand the advantages and disadvantages and pick what is best for you (In our case, since the client side is GWT, it will be easier for us to go for separation to two class hierarchies, one that is DTO/server side and can be also annotated with more server side only annotations, and the other sent to the GWT client code).