Oct 12th, 2012, 08:07 AM
Yes, Again on @Transactional Controllers
I have read a lot in that subject, either in this forum and in places such as StackOverflow. Almost all guys suggest that the best way to deal with transactions is to put @Transactional tags in the service layer, confining single transactions involving more entities in sigle methods of the service.
I can see the advantages of this approach, but I think there are bigger drawbacks, especially from a productivity point of view.
In most real-world apps, there are complex editing views involving more model entities, and associations between them. When the view post the updates, I think the better way to deal with, using Hibernate, is to read the model entities involved from the repository and update their properties and/or associations: Hibernate very naturally change the persistent state of that entities, and when the transaction commits the updates are written to the DB, with no need to call services methods at all!
Moreover, I would want, for performance and security pourposes, that the same methods which reads entities from repository are called inside a read-only transaction when I view data (HTTP GET), and are called inside a read-write transaction when I do a write (HTTP POST,PUT,DELETE), and this can be accomplished only if I have different transaction configuration in my Controller's methods.
The other way (transactional services), we need to use transient / detached object, populated by some mechanism (such as spring-mvc with <form:> tags data binding) and pass them'all to ad-hoc methods in service which merge them in persistent state, which seems to me cumbersome. Why I should write new services methods for each new editing view, where I can do all with model and repository? Finally, why we need a service layer at all but for complex and reusable listing of data?
Last edited by giulio.quaresima; Oct 12th, 2012 at 08:34 AM.
Oct 15th, 2012, 01:22 AM
First of all your services should represent use cases and not simple save/update/delete methods if that is your view of a service I suggest that you read a couple of books.
Also @Transactional on the web layer, what that basically means if that everything was succesful but the rendering of the webpage (for example a thank you screen) the transaction will be rolledback. Because now your screenrendering is part of your database transaction... That would be something I don't want my database transaction to be dependend on (if my page renders or not ).
Also I'm more and more a firm believer that you shouldn't expose your domain objects into your view, your domain should live inside your system... Why? Simply because your view is another representation of your process/model and with a different representation comes a different object model. (To quote Greg Young '1 model cannot be appropriate for reporting, researching, and transactional behaviors).
Oct 15th, 2012, 05:36 AM
About the first point: no, I know what a service layer is, I read a couple of books And, for example, Martin Fowler states: "you probabily don't need a Service Layer if your application's business logic will only have one kind of client [...] and its use case responses don't involve multiple transactional resouces. In this case your Page Controllers can manually control transactions and coordinate whatever response is required, perhaps delegating directly to the Data Source layer." (PEAA, p. 137, bold mine). Following the KISS principle, other guys also says that often there's no need of the service layer in simple applications. But I see that the general opinion from the Spring's community is to have always the service layer and to put transactional logic in it. Why?
As your second point, I would respond that, yes, from a user perspective, if I receive an error screen from the UI, I think that the transaction was been not successful. If the user see an error page, or his browser hangs, or if he see a white page, he naturally think that he should redo the last operation he made.
Finally, about the exposition of the model into the view, I guess that you are right in some situation, and indeed I ask you if do you are referring to the Presentation Model pattern.
Oct 15th, 2012, 06:42 AM
Well we can agree to disagree .
The web-layer is, imho, an integration layer and shouldn't contain business logic only logic to convert the incoming request into something useable by the service/business layer (or whatever you want to call it). So basically your web layer is thin.
Also what is a simple application, imho anything bigger then the todo sample applications or simple crud screen isn't simple anymore. So basically any serious application you are building isn't a simple application (at least the ones I'm building). Most of those also have multiple and different type of transactional resources.
Also manual transaction management in your controller layer is imho different then putting a @Transactional on the method. The first doesn't make the transaction dependend on the rendering of a screen/page, the latter is (or at least can be).
Also the service layer is more then just the transactional layer it is the heart (well at least the outer shell) of your application on which you add transactions, security, logging etc. and should be independend of the client (web, web service, xml, jms or whatever). I still find it a nice abstraction and makes me think about the system (what it does or should do) and the web (Controllers) are nothing more then an integration layer. Which is also nice from the perspective of Single Responsibility Principle.
I still do the same in a plain JEE application when using JSF and EJB/CDI. But that is probably also personal preference and you could write your whole applicaiton in JSF Managed Beans if you want, not sure if that should be done or is what you should want.
Tags for this Thread