• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Why is with a many-to-many the response data recursive...?

 
Ranch Hand
Posts: 71
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,

I have a many-to-many relation defined like:

My Role entity:

If I do a GET with Postman and the parts mentioned commented out are inactive, than I get in my opinion the right data for the response:


Technically I have find out were it comes from, if i activate the lines which I have mentioned "commented out", than it is getting recurence!!??
I have roles added to the employee that's good. But the GET is also returning the roles wiht the employee etc.
My Question: why is this made in this way? And when do I need this? I mean I can't imagine if you are working on an entity, that a response as shown here beneath would be used for the frontend, or...

 
Sheriff
Posts: 22783
131
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
1) When an EmployeeModel instance is serialized, all of its properties are included. One of those properties is roles. This is a List<Role>, and each element is serialized.
2) When these Role instances are serialized, all of their properties are included. One of those properties is employeeRoleModel. This is a List<EmployeeModel>, and each element is serialized.
3) See 1.

There are some ways to fix this. One is to create POJOs for your REST responses. You end up mostly duplicating your class, but you can easily leave out the things you don't want.
Another way to fix this is to mark the employeeRoleModel as ignored during serialization. How to do this depends on the serialization framework. For instance, for Jackson you'd use @JsonIgnore.

I prefer the first way, because
  • it allows me to create different POJOs for retrieving EmployeeModel instances with nested Role instances, or the other way around. If you ignore these in your entities, you can only have one of these options
  • it will ignore anything I don't want. That includes any properties added by the JPA framework (I remember TopLink adding its own properties)
  •  
    Nico van de Kamp
    Ranch Hand
    Posts: 71
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Hello Rob,

    Thanks. I don’t know if I understand you but do you mean by creating different POJO’s.
    The Role class I have made and with commented out List<EmployeeModel> employeeModel, so that the employeeRoleModel properties are not included
    And make another Role POJO for maintenance screen of Role, because Role need to be filled with reference data.

    Is that what you mean?
     
    Rob Spoor
    Sheriff
    Posts: 22783
    131
    Eclipse IDE Spring VI Editor Chrome Java Windows
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    With POJO (plain old Java object) i mean a simple object that has fields, getters and setters, but nothing JPA related.

    To expose employees, you'd need two classes:
    * EmployeeDto: contains all scalar properties (String, numeric, etc) from EmployeeModel, as well as a List<EmployeeRoleDto>
    * EmployeeRoleDto: contains only scalar properties from Role; no property for EmployeeDto

    If you need to expose roles with their employees, you can create similar classes RoleDto and RoleEmployeeDto, where RoleDto has a List<RoleEmployeeDto> and RoleEmployeeDto does not have any link to RoleDto.
     
    Nico van de Kamp
    Ranch Hand
    Posts: 71
    1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Rob,

    Again 'slowly' I think that I understand what I need todo:

    There are some ways to fix this. One is to create POJOs for your REST responses. You end up mostly duplicating your class, but you can easily leave out the things you don't want.

    I prefer the first way, because
    it allows me to create different POJOs for retrieving EmployeeModel instances with nested Role instances, or the other way around. If you ignore these in your entities, you can only have one of these options
    it will ignore anything I don't want. That includes any properties added by the JPA framework (I remember TopLink adding its own properties)



    I was thinking why is it necessary to create new DTO POJOs? I'm satisfied by commented out the private List<EmployeeModel> employeeRoleModel in the Role Entity, there is no recurrence of data in the response, so it is good. But if I want to do something with the Roles POJOs, for instance maintenance CRUD, I'm getting in trouble or I need to define a new Role Entity or something like that if possible

    Now I return for my REST responses the 'emloyeeModel', which I think have to replace by the new POJOs EmployeeModelDTO class instance. Here I define the EmployeeModelDto (which is than more or less duplicate with EmployeeModel), AND return the EmployeeModelDto as response to frontend(Postman), that is the most important thing to realize/understand.

    Another way to fix this is to mark the employeeRoleModel as ignored during serialization. How to do this depends on the serialization framework. For instance, for Jackson you'd use @JsonIgnore.

    I see code where they have more or less choosen for this solution.

    I have the feeling of you're first approach is better because it is more flexible and is further independent what is happening in other entity's - loosely coupled.
     
    Rob Spoor
    Sheriff
    Posts: 22783
    131
    Eclipse IDE Spring VI Editor Chrome Java Windows
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Right. So all you need to do is:
    * create the DTOs
    * map entity instances to DTO instances
    * return the DTO instance instead of the entity

    One thing to keep in mind is that either the roles list in the EmpoyeeModel entity needs to be eager, or you need to retrieve its contents while the transaction is still active. Otherwise, you'll have a detached entity and you'll get an exception when you try to access the roles. You can perform the mapping inside the transaction, or ensure the roles are fetched. A trick is to call getRoles().size(); calling getRoles() alone doesn't force a trip to the database, retrieving its size (or any element) does.
     
    With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
    reply
      Bookmark Topic Watch Topic
    • New Topic