11

Scenario:

  • Stack: Java, Spring, Hibernate.
  • Model: Client-Server Application.
  • Pattern: Model-View-Controller (MVC).

The Service Layer classes has three behaviors:

  1. Some services have the business rule within the methods and delegate the persistence to the application. Like:

    EntityManager.save(entity);

  2. Some services simply call a database function (passing parameters) Like:

    CallableStatement cls = con.prepareCall("{call databaseFunction(args)}");

  3. Some services have methods with both behaviors.

My questions:

  1. Is there any problem in having application services call - directly - database functions? Is not this considered bad practice? What would be an architecture model applicable to a project like this?
  2. Is there any problem in having the behavior mix in the same service? Such as transactions and consistency?
  3. In the case of maintenance, does this encapsulation make it obscure to the developer that he should also change the functions in the database? How to avoid this?
  4. Does this scenario happen in other applications around the world or was it just an architectural error?
linuxunil
  • 1,441
  • 10
  • 17
  • This question is similar but not exactly the same.. http://softwareengineering.stackexchange.com/questions/180012/is-there-any-reason-not-to-go-directly-from-client-side-javascript-to-a-database – Jon Raynor Dec 06 '16 at 18:39
  • 1
    It might interest. [How essential is it to make a service layer?](http://softwareengineering.stackexchange.com/questions/162399/how-essential-is-it-to-make-a-service-layer?rq=1) and [Service layer vs DAO — Why both?](http://softwareengineering.stackexchange.com/questions/220909/service-layer-vs-dao-why-both?noredirect=1&lq=1) – Laiv Dec 07 '16 at 08:28

2 Answers2

7

Is there any problem in having application services call - directly - database functions? Is not this considered bad practice?

I think there is. You are placing a knowledge about the database internals to the application service. Changing database in any way (changing storage engine or even renaming a field or creating index) might require you to change application service and that violates SRP.

What would be an architecture model applicable to a project like this?

See comment below.

Is there any problem in having the behavior mix in the same service? Such as transactions and consistency?

I do not believe there is a technical problem, but there is a logical one. You just mix two approaches in the application making it vague, less structured, hard to adapt to changes. See comments above about violating SRP also.

In the case of maintenance, does this encapsulation make it obscure to the developer that he should also change the functions in the database?

Sure it does.

How to avoid this?

Place methods and functions, that directly work with database into a separate level of abstraction (be it a DAO layer or a simple repository pattern - depends on the complexity of your application)

Does this scenario happen in other applications around the world or was it just an architectural error?

I think in our world everything happens ;)

Vladislav Rastrusny
  • 1,844
  • 12
  • 14
  • If I understand correctly, there may be a technical issue in that if updates are happening in functions/stored-procs and also through a ORM, the states of a given transaction is very difficult to reason about. While the application might work in it's current state, a small change could cascade into some really big problems. My experience with Hibernate is that if you don't let it manage the entire set of tables it works with, you will have a lot of annoying issues. – JimmyJames Dec 07 '16 at 15:16
  • nice and concise answer. SRP was the first thing that came to my mind when i first looked at the code. Some co-workers say that the method does not violate SRP due to the fact that it only call the database function. But some of those functions do selects, inserts and updates. So it does or not violate SRP? (maybe this itself is another question to discuss separatedly?) – linuxunil Dec 07 '16 at 16:04
  • 1
    +1 for that line _I think in our world everything happens ;)_ – linuxunil Dec 07 '16 at 16:06
  • @linuxunil SRP should be respected on all levels of architecture. In my case I meant SRP at the level of the service, not at the method level. @ JimmyJames Yep. Most of the ORMs do not work well with the stored procedures. But sometimes stored proces are necessary. – Vladislav Rastrusny Dec 08 '16 at 08:00
3

According to what you said there's a service layer so the architectural pattern that seems fit is Layered Architecture. Further reference

Yeah it is usually a bad practice to do direct database calls on the other than a data access layer, that way the business layer only access an abstraction of the database.

As for the mixing behaviors, using some design pattern as the DAO pattern or Repository pattern could help to delegate that responsibilities thus improving that code.

Some of the advantages of using a design pattern and a ORM is the readability of your code the encapsulation of the responsibilities so if your database access changes your business layer should not change much.

J. Pichardo
  • 911
  • 6
  • 15
  • Not sure why this was down-voted. This answer recommends **separating** code that deals with different **concerns**. Feels like a principal of programming here... not sure what it is... Man. If only I could think of the name. +1 BTW – Greg Burghardt Dec 07 '16 at 15:28
  • Isn't it one of the solid principles? – J. Pichardo Dec 07 '16 at 15:30
  • 3
    No. The "S" in SOLID is the **S**ingle Responsibility Principal (SRP). But Separation of Concerns, which you are recommending, is a valid reason for separating service logic from data access logic. The other answer by Vladislav mentions the Single Responsibility Principal. Frankly, The SRP and Separation of Concerns go together well, like wine and cheese. – Greg Burghardt Dec 07 '16 at 15:33