2

I am working on a REST API with the following structure:

  • controller: classes that define the endpoints to obtain/create entities.
  • model: classes that represent the entities that are stored in each database table.
  • repository: classes that extend JpaRepository, it provides the methods to perform HQL queries on each model.
  • service / serviceimpl: classes that define the logic to obtain or create an entity from a model.

There is a table in the database that has multiple @OneToMany relationships with other tables. From the front-end, I will receive a json with the data to create a new entity from this table, but this json will also contain information to create entities from other tables that are related to the main one. This gives me the following problems:

  • The model class for the main entity has a lot of @Transient attributes because they send me information that shouldn't be mapped directly to a DB table, because I'll have to implement the logic to create the actual instances. (where should I do it? currently the logic to get child instances is implemented in the parent's ServiceImpl class, so the code is very long and hard to maintain).
  • I must persist each instance separately: to create the child entities I must provide an id of the parent entity. Because of this, I need to use JpaRepository's .save() method a first time to insert the parent entity and get its id. Then from that id I do the logic to create all the child entities and persist each one. In case there is a problem in the middle of the method, some instances will have been persisted and others not, this implies saving incomplete data in the DB.

The result of this is a very dirty and difficult to maintain model and ServiceImpl class. But I have to do that, since the front-end devs want to send me a single json with the information of everything that needs to be created, and they decided that the back-end implements all the logic to create the entities.

In what classes and in what order would you define the methods to do this as cleanly and safely as possible?

HopFr0g
  • 71
  • 7

1 Answers1

0

If you use @Transactions and have auto-commit: false, it will commit the changes at the end of the transaction. So if you created the main object, then create all other subsequent objects and if any of them fails, the transaction will rollback.

Regarding the order of creation:

  • i would make a creation manager that will handle these. So for example
  • the json that you receive from the FE is

Apply what says in this answer in the below method.

{
"name": "abc",
"children-ofTypeA": [{
    "name": "abc-child-a"
},
"children-ofTypeB": [{
    "name": "abc-child-b"
}],
"some-other-prop-that-we-don't-care": {..}
}
class MainObject {
 private String name:
 private List<A> childrenA;
 private List<B> childrenB;
}

You get this json and you pass it to CreationManager for example

   class CreationManager {
      @Transactional
      public void create(StructureAbove json) {    
        // use a mapper of something to create the object
        var mainObj = createMainObjFrom(json); 
        
        //apply what says in the posted link
       }
    }

ALex
  • 673
  • 1
  • 6
  • 19