I have looked up a lot of information about the DAO pattern and I get the point of it. But I feel like most explainations aren't telling the whole story and by that I mean where would you actually use your DAO. So for example if I have a User class and a corresponding UserDAO that is able to save and restore users for me, which is the correct way:
The controller creates the User object and passes it to the UserDAO to save it to the database
The controller creates the User object and in its constructor the user object makes a call to the userDAO in order to save itself into the database
This is a code smell and you are missing an extra class "UserManager" which the controller will ask to create the user. The UserManager is responsible for creating the user and asking the UserDAO to save it
I really feel like the third option is the best, because all that the controller is responsible for is delegating the request to the correct model object.
What is your favorite way? Am I missing something here ?
From my experience with DAOs, the first approach is the only correct one. The reason is that it has the clearest responsibilities and produces the least clutter (well, some very respectable programmers regard DAOs themselves as clutter. Adam Bien sees the original DAO pattern already implemented in the EntityManager and further DAOs to be mostly unnecessary "pipes")
Approach 2 binds the model to the DAO, creating an "upstream dependency". What I mean is that usually the models are distributed as separate packages and are (and should be) ignorant of the details of their persistence. A similar pattern to what you are describing is the Active Record pattern. It is widely used in Ruby on Rails but has not been implemented with equal elegance and simplicity in Java.
Approach 3 - what is supposed to be the point of the UserManager? In your example the Manager performs 2 tasks - it has the duties of a User factory and is a proxy for persistence requests. If it is a factory and you need one, you should name it UserFactory without imposing additional tasks on it. As for the proxy - why should you need it?
IMHO most classes named ...Manager have a smell. The name itself suggests that the class has no clear purpose. Whenever I have an urge to name a class ...Manager, it's a signal for me to find a better fitting name or to think hard about my architecture.
For the first approach; IMHO, controller calling a method on a DAO object is not a good design. Controllers must be asking "service" level objects about business. How these "services" persist the data is not a concern for the controller.
For the second approach; sometimes you may want to just create the object, so constructor duty and persisting duty must not be tightly coupled like this.
Lastly, the manager or the service objects is a good abstraction for the layered architecture. This way you can group the business flows in the appropriate classes and methods.
But for Play, companion objects of case classes are also a good candidate to use as DAO. The singleton nature of these objects make it a good candidate.
case class TicketResponse(appId: String, ticket: String, ts: String)
object TicketResponse{
implicit val ticketWrites = Json.writes[TicketResponse]
def save(response: TicketResponse) = {
val result = DB.withConnection {
implicit connection =>
SQL("insert into tickets(ticket, appid, ts)"
+ " values ({ticket},{appid},{ts})")
.on('ticket -> response.ticket, 'appid -> response.appId, 'ts -> response.ts).executeInsert()
}
}
}
The Data Access Object (DAO) should be used closer to the data access layer of your application.
The data access object actually does the data access activities. So it is part of data access layer.
The architecture layers before DAO could vary in projects.
Controllers are basically for controlling the request flow. So they are kind of close to UI.
Although, a Manager, Handler is a bad idea, we could still add a layer between controller and DAO. So controller will pre-process the data that is coming from a request or going out (data sanity, security, localization, i18n, transform to JSON, etc). It sends data to service in the form of domain objects (User in this case). The service will invoke some business logic on this user or use it for some business logic. And it would then pass it to DAO.
Having the business logic in controller layer is not good if you are supporting multiple clients like JSPs, WebServices, handheld devices, etc.
Assuming Controller means the "C" in MVC, your third option is the right approach. Generally speaking Controller code extends or follows the conventions of a framework. One of the ideals of MVC is swapping frameworks, which is really the Controller, should be relatively easy. Controllers should just move data back and forth between the model and view layers.
From a model perspective, Controllers should interact with a service layer - a contextual boundary - in sitting front of the domain model. The UserManager object would be an example of a piece that you would consider part of your service layer - that is the domain model's public API.
for typical webapp i will prefer play framework with play's JPA and database implementation. It much more productive way.
please take a look here http://www.playframework.org/documentation/1.2.5/jpa
and here
http://www.playframework.org/documentation/1.2.5/guide1 and http://www.playframework.org/documentation/1.2.5/guide2
That's it))
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'm (trying to :) using spring-boot-starter-data-rest in my spring boot app to quickly serve the model through true, fullblown, restFULL api. That works great.
Question 1 (Security):
The advantage of Spring JpaRepository is I don't need to code basic functions (save, findAll, etc). Is it possible to secure these auto-implemented methods without overriding all of them (wasting what Spring provided for me)? i.e.:
public interface BookRepository extends JpaRepository<Book, Long> {
#PreAuthorize("hasRole('ROLE_ADMIN')")
<S extends Book> Book save(Book book);
}
.
Question 2 (Security):
How to secure a JpaRepository to prevent updating items the loggeg-in user is not an owner?
i.e.: User is allowed to modify only his/her own properties.
i.e.2: User is allowed to modify/delete only the Posts he/she created.
Sample code is highly welcome here.
.
Question 3 (DTOs):
Some time ago I had an argue with a developer friend: He ensisted that there MUST be DTOs returned from Spring MVC controllers. Even if the DTO is 1-1 copy of the model object. Then I reserched, asked other guys and confirmed it: DTOs are required to divide/segregate the application layers.
How this relates to JpaRepositories? How to use DTOs with Spring auto serverd rest repos? Should I DTOs at all?
Thanks for your hints/answers in advance !
Question 1: Security
Some old docs mention:
[...] you expose a pre-defined set of operations to clients that are not under you control, it’s pretty much all or nothing until now. There’s seemingly no way to only expose read operations while hiding state changing operations entirely.
which implies that all methods are automatically inherited (also, as per standard java inheritance behavior).
As per the #PreAuhtorize docs, you can place the annotation also on a class / interface declaration.
So you could just have one basic interface extend JpaRepository
#NoRepositoryBean // tell Spring not create instances of this one
#PreAuthorize("hasRole('ROLE_ADMIN')") // all methods will inherit this behavior
interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {}
and then have all of your Repository's extend BaseRepository.
Question 2: Security
I'm going to be a little more general on this one.
In order to correctly regulate access to entities within your application and define what-can-see-what, you should always separate your project into different layers.
A good starting point would be:
layer-web (or presentation-layer): access to layer-business, no access to the db-layer. Can see DTO models but not DB models
layer-business (or business-layer): access to the db-layer but no access to the DAO
layer-db (or data-layer): convert DTO -> DB model. Persist objects and provide query results
In your case, I believe that the right thing to do, would be therefore to check the role in the layer-business, before the request even reaches the Repository class.
#Service
public interface BookService {
#PreAuthorize("hasRole('ROLE_ADMIN')")
ActionResult saveToDatabase(final BookDTO book);
}
or, as seen before
#Service
#PreAuthorize("hasRole('ROLE_ADMIN')")
public interface BookService {
ActionResult saveToDatabase(final BookDTO book);
}
Also, ensuring a user can modify only its own objects can be done in many ways.
Spring provides all necessary resources to do that, as this answer points out.
Or, if you are familiar with AOP you can implement your own logic.
E.g (dummyCode):
#Service
public interface BookService {
// custom annotation here
#RequireUserOwnership(allowAdmin = false)
ActionResult saveToDatabase(final BookDTO book);
}
And the check:
public class EnsureUserOwnershipInterceptor implements MethodInterceptor {
#Autowired
private AuthenticationService authenticationService;
#Override
public Object invoke(Invocation invocation) throws Throwable {
// 1. get the BookDTO argument from the invocation
// 2. get the current user from the auth service
// 3. ensure the owner ID and the current user ID match
// ...
}
}
Useful resources about AOP can be found here and here.
Question 3: DTO's and DB models
Should I DTOs at all?
Yes, yes you should. Even if your projects has only a few models and your are just programming for fun (deploying only on localhost, learning, ...).
The sooner you get into the habit of separating your models, the better it is.
Also, conceptually, one is an object coming from an unknown source, the other represents a table in your database.
How this relates to JpaRepositories?
How to use DTOs with Spring auto serverd rest repos?
Now that's the point! You can't put DTO's into #Repositorys. You are forced to convert one to another. At the same point you are also forced to verify that the conversion is valid.
You are basically ensuring that DTOs (dirty data) will not touch the database in any way, and you are placing a wall made of logical constraints between the database and the rest of the application.
Also I am aware of Spring integrating well with model-conversion frameworks.
So, what are the advantages of a multi-layer / modular web-application?
Applications can grow very quickly. Especially when you have many developers working on it. Some developers tend to look for the quickest solution and implement dirty tricks or change access modifiers to finish the job asap. You should force people to gain access to certain resources only through some explicitly defined channels.
The more rules you set from the beginning, the longer the correct programming pattern will be followed. I have seen banking application become a complete mess after less then a year. When a hotfix was required, changing some code would create two-three other bugs.
You may reach a point where the application is consuming too many OS resources. If you, let's say, have a module module-batch containing background-jobs for your application, it will be way easier to extract it and implement it into another application. If your module contains logic that queries the database, access any type of data, provides API for the front-end, ecc... you will be basically forced to export all your code into your new application. Refactoring will be a pain in the neck at that point.
Imagine you want to hire some database experts to analyze the queries your application does. With a well-defined and separated logic you can give them access only to the necessary modules instead of the whole application. The same applies to front-end freelancers ecc... I have lived this situation as well. The company wanted database experts to fix the queries done by the application but did not want them to have access to the whole code. At the end, they renounced to the database optimization because that would have exposed too much sensitive information externally.
And what are the advantages of DTO / DB model separation?
DTO's will not touch the database. This gives you more security against attacks coming from the outside
You can decide what goes on the other side. Your DTO's do not need to implement all the fields as the db model. Actually you can even have a DAO map to many DTO's or the other way around. There is lots of information that shouldn't reach the front-end, and with the DTO's you can easily do that.
DTO are in general liter than #Entity models. Whereas entities are mapped (e.g #OneToMany) to other entities, DTO's may just contain the id field of the mapped objects.
You do not want to have database objects hanging around for too long; and neither being passed around by methods of your application. Many framework commit database transactions at the end of each method, which means any involuntary change done onto the database entity may be committed into the db.
Personally, I believe that any respectful web-application should strongly separate layers, each with its responsibility and limited visibility to other layers.
Differentiation between database models and data transfer objects is also a good pattern to follow.
At the end this is only my opinion though; many argue that the DTO pattern is outdated and causes unnecessary code repetition any many argue that to much separation leans to difficulty in maintaining the code. So, you should always consult different sources and then apply what works best for you.
Also interesting:
SE: What is the point of using DTO (Data Transfer Objects)?
Lessons Learned: Don't Expose EF Entities to the Client Directly
Guice Tutorial – method interception (old but gold)
SO: Large Enterprise Java Application - Modularization
Microsoft Docs: Layered Application Guidelines
The 5-layer architecture
I have design issue when implement 1 simple web application.
I use struts2 web controller, spring’s IOC and Hibernate as persist layer.
Because this web application is very simple at begging. So I only have 2 layers:
1 DAO layer which used to access database. Almost every table have related DAO.
2 Action layer. User struts2.
I am satisfy with this architecture because can quickly implement my web application.
As project become bigger, I found the action layer become big and complex, and very hard to re-use.
I try to create service layer, to solve complex business logic is good, but my application still have a lot of simply logic. E.g: Load 1 object, save 1 object, and get collection by some condition and display it to webpage. If give each simple DB access method have corresponding service method. Still cost a lot of effort. How can solve this issue?
And I think, if service layer existing, direct call DAO layer still not good design for my application.
Is any good solution for this kind of small web application?
When planing the different layers in a web application it is good practice to explicitly protect attributes and associations in your model from being manipulated without providing an identity context.
This is something that should neither be done in the DAO layer nor in the Controller. You should wrap your DAO layer in a service layer and have the controller only talk to the services not the DAO directly.
Protecting your model against unwanted manipulation means that you for instance adapt the amount of information passed in a data structure between Controller and Service to the actual operation that you want to perform.
For instance: adding or removing an element from a collection is an explicit operation in the service, it does not happen implicitly by manipulating a collection as a member of a DAO object and passing that DAO back into the service.
Instead your service may look like this:
+ getAllCompanies(): CompanyType[*]
+ getAllEmployeesOfCompany(c: CompanyType) : EmployeeType[*]
+ addEmployeeToCompany(e: EmployeeType, c: CompanyType)
+ removeEmployeeFromCompany(e: EmployeeType, c: CompanyType)
The additional benefit of such an architecture is that the service layer serves as boundary for your transactions. Using the methods of your controller as boundary for your transactions is in fact a very bad habbit. You could even call it an anti-pattern. Why? Because for instance it would mean that when your client hangs up it would roll back your transaction. That is clearly unwanted in 99% of the cases.
As #mwhs commented, Apache Isis provides plenty of guidance on layering your app. To figure out whether it fits your requirements, you could run through this tutorial I presented at a recent conference.
Suppose i have class USER with attributes.
In some examples i see UserService class defined for some functions.
I am confused which things or functions should written in User Class and which things in UserService.
For e,g If i want to write some function To Validate users in database like
validate(user,pass)
Where should write those function
Also if i have class ShoppingProducts
and i want to get all prodcuts shopped by particular user in which class should i write that function i mean in product class or UserService or ProductService
This is a typical example of domain model vs anemic model.
There's a lot of theory in this discussion, but a practical advice from me is to:
put all methods that can operate on the User properties only in the User class.
put all methods that require database access, accessing web services, or other layers, in the service.
See this related article of mine.
I won't go into the battle of domain vs anemic or SOA data separate from behavior.
I will say that I think of service's as behavior that spreads across multiple domains (multiple domain objects) and deals with data transfer objects (ie don't put the DTOs in your domain objects).
With REST being so popular these days and the fact the Resources (REST since) are not Models you always seem to need DTOs and Service classes.
On other hand with AspectJ, Annotations and some other magic you can really push the edge of Domain Driven design but I still think you should not reference other domain objects in a domain object.
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.