This question already has answers here:
How to use DTO in JSF + Spring + Hibernate
(2 answers)
JSF Service Layer
(2 answers)
Closed 7 years ago.
I am developing a java web application and am trying to follow some patterns like dao/dto. At the moment i am thinking about such base architecture layers:
I ran into some questions regarding the layers. The scheme would go as such: DAO takes in DTO and returns objects(entities) from DataBase, Service layer also takes in DTO, uses DAO and does all the required logic with the returned objects. UI Bean, Service, DAO and DTO classes are Entity specific - each entity has its own layers.
Now would i need the UI bean to use in views or would that be an overkill and UI views can directly use service classes as ui beans? If no, why would i need UI bean?
Another question is regarding DTO. I have created entities with all the required properties and as i understand DTO classes are like reflections of Entity classes. So why would i need these DTO classes and if i use them i recon it would require some converting from entity to dto and vice versa. Do i do the converting in Service layer? Would views (for eg. html pages) also display DTO object properties not actual Entities (as in calling #{UIBean.entityProperty})?
First of all, I would use the DTO beans on the front-end part only, but since u already mention UI-beans, i suppose these will do the trick just fine, the facade uses these to pass them to the controller for displaying your web-components.
in between the Service and the facade you map the entities of the backend towards dto-beans.
In this way your front-end will be completely loosely coupled to your backend.
Regarding your 2nd question I would like to point out an exact valable reason why your UI should always use dto or view beans.
You can combine several backend entity-beans into one dto bean for easier processing on the front-end.
In general I keep always in mind DTO's for public acces, eta a web-service exposing it or a web-front end or a swing app, or...
Entity classes only used in dao and service layer never further up.
As rule of thumb try to divide logical layers according to your context. Inspire you of the theory but use it with care. I give you my humble understanding of layer's interest with few examples. This vision is of course not complete but I hope it will help you to answer your questions.
So is it overkill to use UIBean instead of Service DTO ? I would say it depends of your context.
Maybe there are user inputs data inside your UI beans ? You have to validate them with JSR 303 annotations for example. If those annotations have a meaning in this layer they are useless for underneath layers. That's why you will have a UIBean with JSR 303 annotations and a DTOBean without JSR 303 annotations.
But if they are exactly the same why duplicate ? Maybe at UIBean layer a date could be represented as a String type and you want to manipulate Date type instead of String at DTO layer. That's why you need to adapt your data between layers to work with objects that make sense to a particular layer. For example, you could add a BOAdapter (between UIView and Service) and DTOAdapter (between Service and DAO). Those adapters are usefull for transforming your data inside each POJO's format. For example, you could have in your BO(=UIBean) a date expressed inside three strings and you want a Date object for DTO so you transform it inside the BOAdapter:
public class BOAdapter(){
private BOAdapter(){}
public static DTO toDTO(BO objectBO){
DTO objectDTO = new DTO();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-aa");
objectDTO.setDate(df.parse(objectBO.getYear()+"-"+objectBO.getMonth()+"-"+objectBO.getDay());
[...]
}
}
Why I need DTOAdapter ? Maybe you have a database that contains at least two tables Customers and Adresses with an integrity constraint between them. JPA will automatically generate the right code. But do you really need all this code up to UIView ? I mean if the functionnality you are coding needs only the name, surname and date of birth of your customer, their adress is useless. Again that's why you need to adapt your data between layers to work with objects that make sense to a particular layer. In this case you could create a DTO object only with name, surname and date of birth information and create a method inside your DTOadapter to transform your custom DTO into an heavy JPA object to work properly with database.
But I need the whole entity for coding my fonctionnality ? Maybe you need to add validation constraints inside this layer besides JSR 303. So it could be interesting to have DTO classes besides your entity for the same reason as BO objects.
But my entity is big how duplicate it easily ? Try to use a tool to map data (like dozer) automatically. If it is not too big do it manually.
Since you have Spring tag,
I will replace your [DAO] with Spring Data Repository. So most of the time, you write interface method / #query annotation, Spring Data write implement.
Replace DTO with JPA Entity. So I could use some reverse engineering.
[UI Bean] will most be composite of JPA Entity. With some validation
Related
I have a Spring Boot application with a service that returns a Spring Data entity that is exposed to a controller. The problem is that I know it's not a good idea to use entities outside of DB transactions, so what would be the best practices?
Consider the following service:
#Transactional
public MyData getMyData(Long id) {
return myDataRepository.findById(id);
}
where MyData is a database #Entity and myDataRepository is a JpaRepository
This service method is called from a controller class, that sends this object in JSON format to a client that calls this method.
#RequestMapping("/")
public ResponseEntity<?> getMyData(#RequestParam Long id) {
return myService.getMyData(id);
}
If I expose MyData to a controller, then it will be exposed outside of a transaction and might cause all kind of hibernate errors. What are the best practices for these scenarios? Should I convert entity to POJO in side the service and return MyDataPOJO instead of MyData in MyService?
Using entities outside of transactions does not necessarily lead to problems; it may actually have valid use cases. However, there's quite a few variables at play and once you let them out of your sight things may and will go south. Consider the following scenarios:
Your entity doesn't have any relationships to other entities or those relationships are pretty shallow and eagerly fetched. You retrieve that entity from repository, detach it from persistence unit (implicitly or explicitly) and pass to controller. Controller does not attempt to modify the entity; it only serializes it into JSON - totally safe.
Same as above but controller modifies the entity before serializing it into JSON - again, totally safe (just don't expect those changes to be reflected in DB)
Same as above, but you've forgotten to detach the entity from PU - ouch, if controller changes the entity you may either see it reflected in DB or get transaction closed exception; both most likely being unintended consequences.
Same as above, but some of entity's relationships are lazy. Again, you may or may not get any exceptions depending on whether these lazy properties are being accessed or not.
And there are so many more combinations of intentional and unintentional design choices...
As you may see, things can get out of control very quickly. Especially so when your model has to evolve: before long you're going to find yourself fiddling with JSON views, #JsonIgnore, entity projections and so on. Thus the rule of thumb: although it may seem tempting to cut some corners and expose your entities to external layers, it's rarely a good idea. Properly designed solution always has a clear separation of concerns between layers:
Persistence layer never exposes more methods or entities than required by business logic. More over, the same table(s) can and should be mapped into several different entities depending on the use cases they participate in.
Business logic layer (btw this is your API, not the REST services! see below) never leaks any details from persistence layer. Its methods clearly define use cases from the problem domain.
Presentation layer only translates API provided by business logic into one or another form suitable for client and never implements additional use cases. Keep in mind that REST controllers, SOAP services etc logically are all part of presentation layer, not business logic.
So yeah, the short answer is: persistence entities should not be exposed to external layers. One common technique is to use DTOs instead; besides, DTO objects provide additional abstraction layer in case you need to change your entities but leave API intact or vice versa. If at some point your DTOs happen to closely resemble your entities, there are Java bean mapping frameworks like Dozer, Orika, MapStruct, JMapper, ModelMapper etc that help to eliminate the boilerplate code.
Try googling "hexagonal architecture". This is a very interesting concept for designing cleanly separated layers. Here's one of the articles on this subject https://blog.octo.com/en/hexagonal-architecture-three-principles-and-an-implementation-example/; it uses C# examples but they're pretty simple.
You should never leak the internal model to outside resources (in your case - the #RestController). The "POJO" you mentioned is typically called a DTO (Data Transfer Object). The DTO can be defined as an interface on the Service-side and implemented on the Controller-side. The Service would then - as you described - transform the internal model into an instance of the DTO, achieving looser coupling between the Controler and the Service.
By defining the DTO-interface on the service-side, you have the additional benefit that you can optimize your persistence-acces by only fetching the data specified in the corresponding DTO-interface. There is, for example, no need to fetch the friends of a User if the #Controller does not specifically requests them, thus you do not need to perform the additional JOIN in the database (provided you use a database).
I (think I) just understood the differences between Java Entity, VO, POJO, Javabeans, DAO, DTO, etc, I mean, the theory. Now, I'm trying to understand the implications of the implementations depending on the needs. Who cares if I create a POJO or a JavaBean? At the beginning I will create a POJO if I have no other constraint, until I realise I must make it a Javabean and deal with it's restrictions.
When do you tell yourself: "I need a DTO"? Only for web services or when any client/server call is made? In that case, do you put all the data you need (and the one you think you will need?) in one DTO bunch?
Lastly, in a MVC model, where does each one go? Can I make an entity or a vo in either layer? Where does the DTO go?
Thank you very much
You understood the difference between them, now you need to understand their purpose.
There is a neat definition for each one in this link.
Who cares if I create a POJO or a JavaBean? At the beginning I will create a POJO if I have no other constraint, until I realise I must make it a Javabean and deal with it's restrictions.
You need to think what the purpose of the class is. Is it a standalone class with no annotations that provides functionality but can be isolated (not counting libraries used)? Then it is likely a POJO.
Is it a class that serves as a bridge between layers of your project? Is it annotated? Does it implement some business logic for your project? Then it is a JavaBean.
When do you tell yourself: "I need a DTO"? Only for web services or when any client/server call is made? In that case, do you put all the data you need (and the one you think you will need?) in one DTO bunch?
DTOs are generally used to share information between layers. Their main purpose is isolating Entities so that you can change how your information is persisted from how the information flows through the different beans and controllers in your project.
To know when I need a DTO and when not I follow these rules:
Does the method more than three parameters? Then use a DTO.
Does the method return more than a single parameter? Then use a DTO.
When passing parameters to method calls / from method results: Does each element have more than one type (for Maps you would look at the value)? Then use a Collection of DTOs.
Otherwise use String, int, Long, etc.
Also never mind reusing DTOs even if most of its fields are not used for a specific method, you won't be wasting much memory if it's properly design. On the other hand, don't worry if you need to create new DTOs that share fields with some others, it might be clearer when reviewing your code. Try to find the right balance between too many DTOs and overpopulated DTOs.
Lastly, in a MVC model, where does each one go? Can I make an entity or a vo in either layer? Where does the DTO go?
It depends on how you structure your project. The term layer is a bit open as it can refer to each of the MVC elements and to the Data/Business/Client architecture (when I used the word layer in this answer, I'm talking about the later classification).
It is a good practice to separate each layer in a different project (specially in large projects). This is a common structure I use for enterprise web applications:
ProjectNameDao: Includes database access methods and entities.
ProjectNameBo: Includes all the business logic. Shares information with the other layers by using DTOs. It is, along ProjectNameDao, the Model in a MVC model.
ProjectNameWeb: Includes views and controllers from the MVC model.
ProjectNameDto: Includes all DTOs.
ProjectNameUtils: Shared utils, normally POJOs that hold constant values or provide basic functionality like Date formatting.
This structure needs to be adapted to whatever your requirements are, of course.
#Entity
class MyEntity {
//some properties to be explosed to REST, some not
}
I have some database classes that I want to explose via REST using spring.
Is it advisable to create a DTO for each database class, copying over all properties needed to be exposed.
Because certainly some fields like the id should never be available via rest. But these fields can maybe be annotated accordingly so they are ignored during REST offer?
Is writing DTOs still advisable today if they just serve as plain data containers that get the fields copied over from DB?
Some points I can think while deciding:
Arguments against common model for persistence & web service
In many applications the rest services are written to provide you a fully constructed object & not really a normalized view of the data. For example your rest service may return an Employee object with a Department object, wheras your db model just has a deparment id
Modifications in 1 model do not affect the other. For example you decide to change a String in the persistence model to an integer, you may still be ok with keeping it as a string in your rest service
You may have attributes in the rest model which make no sense to be on the persistence model or vice versa
If you are distributing your model jar (like a client API) then it may end up with a dependency on your persistence framework which your clients may not want/support.
Arguments supporting common model for persistence & web service
Avoid copying/cloning data for every interaction
Avoid duplicate maintenance or possible issues when an attribute is added in 1 model and forgotten in another
In my experience if you are creating services exclusively to be consumed by your own application (like a UI) and have tight control on those services, you might get away with using a common model
However if the rest API is intended for broader use and for longevity I would go with separate models. You can use spring's beanutils to ease the conversion of models from one format to other. See example here
My application has about 50 entities that are displayed in grid format in the UI. All 50 entities have CRUD operations. Most of the operations have the standard flow
ie. for get, read entities from repository, convert to DTO and return a list of DTO's.
for create/update/delete - get DTO's - convert to entities, use repository to create/update/delete on DB, return updated DTOs
Mind you that for SOME entities, there are also some entity specific operations that have to be done.
Currently, we have a get/create/update/delete method for all our entities like
getProducts
createProducts
updateProducts
getCustomers
createCustomers
updateCustomers
in each of these methods, we use the Product/Customer repository to perform the CRUD operation AFTER conversion from entity -> dto and vice versa.
I feel there is a lot of code repetition and there must be a way by which we can remove so many of these methods.
Can i use some pattern (COMMAND PATTERN) to get away with code repetition?
Have a look at the Spring Data JPA or here project. It does away with boilerplate code for DAO.
I believe it basically uses AOP to interpret calls like
findByNameandpassword (String name,String passwd)
to do a query based upon the parameters passed in selecting the fields in the method name (only an interface).
Being a spring project it has very minimal requirements for spring libraries.
Basically, you have 2 ways to do this.
First way: Code generation
Write a class that can generate the code given a database schema.
Note that this you will create basic classes for each entity.
If you have custom code (code specific to certain entities) you can put that in subclasses so that it doesn't get overwritten when you regenerate the basic classes.
Object instatiation should be via Factory methods so that the correct subclass is used.
Make sure you add comments in the generated code that clearly states that the code is generated automatically (so that people don't start editing them directly).
Second way: Reflection
This solution, while being more elegant, is also more complex.
Instead of generating one basic class for each entity you have one basic class that can handle any entity. The class would be using reflection to access the DTO:s.
If you have custom code (code specific to certain entities) you can put that in other classes. These other classes would be injected into the generic class.
Using reflection would require a strict naming policy on your DTO:s.
Conclusion
I have been in a project using the first method in a migration project to generate DTO classes for the service interface between the new application server (running java) and the fat clients and it worked quite well. We had more than 100 generated DTO classes. I am aware that what you are attempting is slighty different. Editing database records is a generic problem (all projects need it) but there aren't (m)any frameworks for it.
I have been thinking about creating a generic tool or framework for it but I have never gotten around to it.
In my Spring MVC application I am using DTO in the presentation layer in order to encapsulate the domain model in the service layer. The DTO's are being used as the spring form backing objects.
hence my services look something like this:
userService.storeUser(NewUserRequestDTO req);
The service layer will translate DTO -> Domain object and do the rest of the work.
Now my problem is that when I want to retrieve a DTO from the service to perform say an Update or Display I can't seem to find a better way to do it then to have multiple methods for the lookup that return different DTO's like...
EditUserRequestDTO userService.loadUserForEdit(int id);
DisplayUserDTO userService.loadUserForDisplay(int id);
but something does not feel right about this approach. Perhaps the service should not return things like EditUserRequestDTO and the controller should be responsible of assembling a requestDTO from a dedicated form object and vice versa.
The reason do have separate DTO's is that DisplayUserDTO is strongly typed to be read only and also there are many properties of user that are entities from a lookup table in the db (like city and state) so the DisplayUserDTO would have the string description of the properties while the EditUserRequestDTO will have the id's that will back the select drop down lists in the forms.
What do you think?
thanks
I like the stripped down display objects. It's more efficient than building the whole domain object just to display a few fields of it. I have used a similar pattern with one difference. Instead of using an edit version of a DTO, I just used the domain object in the view. It significantly reduced the work of copying data back and forth between objects. I haven't decided if I want to do that now, since I'm using the annotations for JPA and the Bean Validation Framework and mixing the annotations looks messy. But I'm not fond of using DTOs for the sole purpose of keeping domain objects out of the MVC layer. It seems like a lot of work for not much benefit. Also, it might be useful to read Fowler's take on anemic objects. It may not apply exactly, but it's worth thinking about.
1st Edit: reply to below comment.
Yes, I like to use the actual domain objects for all the pages that operate on a single object at a time: edit, view, create, etc.
You said you are taking an existing object and copying the fields you need into a DTO and then passing the DTO as part of the model to your templating engine for a view page (or vice-versa for a create). What does that buy you? The ref to the DTO doesn't weigh any less than the ref to the full domain object, and you have all the extra attribute copying to do. There's no rule that says your templating engine has to use every method on your object.
I would use a small partial domain object if it improves efficiency (no relationship graphs to build), especially for the results of a search. But if the object already exists don't worry about how big or complex it is when you are sticking it in the model to render a page. It doesn't move the object around in memory. It doesn't cause the templating engine stress. It just accesses the methods it needs and ignores the rest.
2nd edit:
Good point. There are situations where you would want a limited set of properties available to the view (ie. different front-end and back-end developers). I should read more carefully before replying. If I were going to do what you want I would probably put separate methods on User (or whatever class) of the form forEdit() and forDisplay(). That way you could just get User from the service layer and tell User to give you the use limited copies of itself. I think maybe that's what I was reaching for with the anemic objects comment.
You should use a DTO and never an ORM in the MVC layer! There are a number of really good questions already asked on this, such as the following: Why should I isolate my domain entities from my presentation layer?
But to add to that question, you should separate them to help prevent the ORM being bound on a post as the potential is there for someone to add an extra field and cause all kinds of mayhem requiring unnecessary extra validation.