3

I'm developing an Java Web Application with Spring, and I have some questions about my architecture. Before showing it, here is the context:

  • I am developing a web application with more than 80 existing tables in the database.
  • Both the application and the database are on the same server machine.
  • My application will grow in the future so that, if necessary, the database will be inside a machine alone, and the web application will access it from another.
  • Now I do everything, but in the future I will have specific professionals in their respective areas and / or layers working side by side with me.
  • (EDIT) I am developing the system from scratch, and therefore, I am responsible for modeling and preparation of the database. In short: I'm doing everything alone.

Here is a general model of my architecture:

enter image description here

There are certain points that I would like to comment (for clarification):

  • The main components were highlighted in white, as SERVICE, DAO, etc. These components communicate by exchanging data with each other, and perform actions.
  • The components in green and gray represent types of data exchanged among the main components.
  • The architecture shows a separation into layers.

In relation to this presented model, I have some questions:

  • The green components represent doubts / confusion. Those with "???", are data types that I do not know. What types of data should I put here? Do I need a translator for this (to exchange the correct type)?
  • Is the other type of written data ("DOMAIN MODEL ENTITY" - this is a JPA entity, @Entity) correct? I believe a DAO layer should only be concerned with these types of objects, making it completely independent to care.
  • I know a DAO type should only be concerned with a single entity, so the query parameters are always their fields / attributes / properties. However, what happens when I have to search for an entity that I need a parameter present in one of it's relationships? For example, search for all users with purchases made last month that had a value greater than X? In this case, I need the details found in the Purchase entity. Do I put this in DAO? And if I have to put it in a service class, I have to set EntityManager inside service also, giving it one more responsibility, which may leave without purpose the DAO persistence layer?
  • Finally, is this architectural model wrong for what I want to do? Is there something that needs to be fixed?

Just to be clear, with this organization, I could effect the following situation:

enter image description here

This scheme / diagram shows how a call would be from a control to a DAO (in case, a user control to a UserDAO).

It is seen that I can choose, for example, with Inversion of Control which persistence implementation I wish to use. I like to know if there is also something wrong here

Thank you.

Note: I'm not looking for a correct way. I know how things are. I am looking to complete this model, and whether it is applicable to what I want to do, taking into account the system maintenance, and the capacity of uncoupling of its components. Just it.

EDIT 2

So... After much thought, research, and break my head with it, I think I could finally come to a conclusion:

  • I'll just kill myself...

... Nah, just kidding! Here's the conclusion:

enter image description here

Each balloon in each component is a introduction of the component itself, revealing their responsibilities. This may seem silly, but it nicely expresses the differences in responsibilities between each one.

In some situations it is not possible to generalize. Not always a service returns a DTO. Similarly, it is not always a service needs simple parameters to carry out an action. Therefore the exchange of data between control and service may vary.

The Application Layer and Business Layer can be the same thing, the same system running on the same server machine. One day you may want to separate things. You may want to turn the Business Layer on a Web Server, useful when you might want to use more than one type of client application to use the services of that particular business.

With code generation tools, you can generate in a matter of minutes things like:

  • Domain Model Entities.
  • DTO.
  • Form Objects (classes).

You can also generate DAO classes with the same tools, but from what I saw, they will not be complete, and will need revision. Service classes are incredibly particular to each case. I believe there is no tool for generating this type of code, and therefore, they need to be written from scratch.

2

The green components represent doubts / confusion. Those with "???", are data types that I do not know. What types of data should I put here? Do I need a translator for this (to exchange the correct type)?

This is a quite a matter of taste, personaly i don't like using DTO, because they mainly duplicate business classes make writing adapter, and mess a lot with features like lazy-loading. Furthermore, every time i need to add a field, i need to add it everywhere and retest the whole thing.

So what i did is having only Business Model and i put every annotation i needed (jpa/jackson) on it.

YES this bind my business model to jpa/jackson, as my application rely heavily on Spring, but well decoupling all of that will add quite a lot of work for something that just won't change. I may add later if i need something else (XML serialization) either others annotation or finaly a DTO layer just for this. This will depends of the complexity of the thing.

Is the other type of written data ("DOMAIN MODEL ENTITY" - this is a JPA entity, @Entity) correct? I believe a DAO layer should only be concerned with these types of objects, making it completely independent to care.

As said before, if you want to use the full power of JPA, don't. Here is question of mine on stackoverflow which i was told the same thing, because abstracting JPA leads to unnecessary complex and inefficient code : https://stackoverflow.com/questions/37811139/good-usage-of-managed-entities-proxies-with-orm

I know a DAO type should only be concerned with a single entity, so the query parameters are always their fields / attributes / properties. However, what happens when I have to search for an entity that I need a parameter present in one of it's relationships? For example, search for all users with purchases made last month that had a value greater than X? In this case, I need the details found in the Purchase entity. Do I put this in DAO? And if I have to put it in a service class, I have to set EntityManager inside service also, giving it one more responsibility, which may leave without purpose the DAO persistence layer?

Your DAO layer is by definition aware of the relationships of your model. So of course he can query on subfields and so on. Following what i've been told i considered my DAO layer to be the Entity Manager, so i only have a service layer this fit as long there is nothing too much specific about your DAO/Service.

Finally, is this architectural model wrong for what I want to do? Is there something that needs to be fixed?

As i said, i did some things differently however your model is good because :

  • DAO only handle persistency and no business logic/transaction.
  • Service handle business logic and transaction.
  • Controller do not handle business logic and transaction.

You have the right bases.

  • I agree that DTO's can be a pain but it is even more a pain once you run into the limitation that your JPA entities and data model are dictating your UI data objects. You said it best though, judge the complexity of your application to make that determination. It is always a tradeoff. – maple_shaft Aug 24 '16 at 13:03
  • @maple_shaft What i forgot to said is that my application is a REST Server, client side is an angularJS application. So i can have different objects if needed. – Walfrat Aug 24 '16 at 13:08
  • There is definitely less complexity and fewer logical layers in your specific instance, so I agree that for your application DTO's are probably overkill and a violation of DRY. What worries me about the OP's situation though is that he is using a legacy database, who knows what kind of schema changes could come in his future? Maybe they replace the database at some point or maybe another application is also using this schema and affecting his data model? More decoupling is always safer here. See my answer for my approach. – maple_shaft Aug 24 '16 at 13:23
  • @Walfrat So you're saying/recommending that I should not use DTO, and to leave my SERVICE, DAO, and CONTROL components just working with the Domain Model entities? And what if my view need to display a summary of data, which may be present/spread in N different Domain Model entities? Indeed, writing DTO may involve writing double or triple code, which also involves writing a translator/assembler for the different models (this seems overkill). Please, I really like to know your opinion. I'm getting confused about what data types can be exchanged between my components. Thank you. – Loa Aug 25 '16 at 5:11
  • @Loa Well that's a special case, and i have that too. For this very case, i use a special wrapper class which will contains only the needed fields and use the Criteria.multiselect() or the jpql syntax select new com.foo.bar.MyDTOClass(a.field1, ...) from .... Same when i need to be able to send some form data into a JSON, i have a dedicated wrapper class that will contains the fields or business objects needed for the process. So i do have some DTO classes, but i don't have any adapter, translator. – Walfrat Aug 25 '16 at 6:51
1

I somewhat disagree with Walfrat's answer, however I think there are some important considerations first that you must decide on before you decide if DTO's are the right choice or not for your application. He is not WRONG in his answer and is in fact correct that DTO's can be a cost to Maintainability and a potential violation of DRY principle, however in your specific situation I think using JPA entities as your Domain Model Entities at the Service and Controller would be a mistake.

I am developing a web application with more than 80 existing tables in the database.

When you have an existing schema that generally means you are phasing out legacy software components and replacing them with new software components. The importance increases in proper decoupling of your layers in this instance because it is also likely at some point that one of two things could conceivably happen in the future:

  1. Your database may be refactored or replaced in the future
  2. Other legacy applications may interact with this database and affect its schema.

In the case of Point 2, even a subtle influence by other legacy software components could send a ripple effect that could cause impacts all the way to your Application layer. (Eg. JPA entity must change to accomodate schema change, Service layer changes, Controller and entity JSON mapping changes, JSP and Javascript changes now as potentially the JSON structure changes, etc...)

I think the case for maintaining DTO's is a strong one in your specific instance. This further decouples your layers and has many benefits:

  1. Each component is more independently unit testable
  2. JPA mapping and entity changes are abstracted from your Service and Controller domain model entity.
  3. JSON mapping and presentation entity binding is decoupled from your database.

I think this is the best approach to your architecture.

  • 2
    I think this is a good answer, and I'm generally in favor of abstraction and reasonable degree of decoupling, but... in nearly 25 years as a software development professional and even though I have often read "database may be refactored or replaced in the future" cited as a reason to justify decoupling, I have never once seen an organization just swap out their database for a different kind of database on any in-use medium-large size system. – Brad Thomas Aug 24 '16 at 13:26
  • 1
    Note : if the author do that, and he has quite complex relationship, he will need to be really carefull about lazy-loading, N+1 problem and so on and test how hibernate/<whatever> will load each entity. For this he may need to add a bunch of method just to get only the rights fiels without loading the others (note that in hibernate, if you trigger one lazy-loading, all other lazy fields are loaded, i don't know how it works for others). This might sound as preemptive optimization, but in 4 years i have already seen enough full database loaded one object by one with hibernate in production! – Walfrat Aug 24 '16 at 13:30
  • @BradThomas I happened to experience database refactoring twice. There are different ways companies can go about it, I have seen one where they replaced tables with new views that represent future tables, however this creates problems. Other times I have seen two databases maintained separately with data streams keeping the two in sync while application components are slowly refactored. Both approaches have their pros and cons but that is off topic really and ancillary to the rationale behind my answer. cont... – maple_shaft Aug 24 '16 at 13:38
  • ... The more pressing concern is that with an existing schema, there is a probability that anything other than the new application could influence the schema and thus the data model. I am assuming it is a constraint out of the OP's control, thus why I think more decoupling is called for. You wouldn't want a data model out of your control to start affecting your application layer. – maple_shaft Aug 24 '16 at 13:41
  • 1
    @Walfrat I belive that what maple_shaft said about DTO is very relevant (in my case), but what you said about Lazy-Loading it is very important too. I went looking for more about this on the internet and I found this. I believe that the post's author makes clear about it. In my case, I might define new methods in the DAO layer to get just enough without Lazy-Loading. What do you think about this all? I'm still analyzing both answers. I am very grateful for the attention (thanks!). Please, I ask for a little more patience. – Loa Aug 24 '16 at 20:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.