How to get consolidated Data in many to many with extra entity approach

Viewed 44

Below are the Entities I have created to achieve Many to Many with an extra entity concept.

Company :

@Getter
@Setter
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "companyId")
public class Company {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long companyId;
    private String companyName;
    
    @OneToMany(mappedBy = "company", fetch = FetchType.EAGER)
    Set<CompanyUserMapping> companyUsers;
}

User :

@Getter
@Setter
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "userId")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long userId;
    private String email;
    private String originalCompanyName;
    
    @OneToMany(mappedBy = "user", fetch = FetchType.EAGER)
    Set<CompanyUserMapping> companyUserMapping;
}

CompanyUserMapping

@Getter
@Setter
@Entity
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class CompanyUserMapping {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "company_id")
    private Company company;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "user_id")
    private User user;
    private boolean isExternal;
    private boolean isActive;
}

Below is the way I am adding company with the user.

{
    "company": {
        "companyName": "XYZ company"
    },
    "user": {
        "email": "sehwag@gmail.com",
        "originalCompanyName": "XYZ company"
    },
    "active": true,
    "external": false
}

And also trying to add the user to the existing company using below snippet.

Optional<User>  optionalUser=userRepository.findByEmail(user.getEmail());
Optional<Company> optionalCompany = companyRepository.findById(companyId);
if(optionalUser.isPresent()) {
    User existingUser=optionalUser.get();
    Optional<CompanyUserMapping> optionalCompanyUserMapping=companyUserMappingRepository.findByCompanyAndUser(optionalCompany.get(),existingUser);
    if(optionalCompanyUserMapping.isPresent()) {
        throw new UserExistsForCompanyException("User exists for this company "+companyId);
    }
    CompanyUserMapping companyUserMapping =new CompanyUserMapping();
    companyUserMapping.setCompany(optionalCompany.get());
    companyUserMapping.setUser(existingUser);
    companyUserMapping.setActive(true);
    companyUserMapping.setExternal(false);      
    CompanyUserMapping savedcompanyUserMapping = companyUserMappingRepository.save(companyUserMapping);
    return new ResponseEntity<CompanyUserMapping>(savedcompanyUserMapping, HttpStatus.CREATED);
}
CompanyUserMapping companyUserMapping =new CompanyUserMapping();
companyUserMapping.setCompany(optionalCompany.get());
companyUserMapping.setUser(user);
companyUserMapping.setActive(true);
companyUserMapping.setExternal(false);      
CompanyUserMapping savedcompanyUserMapping = companyUserMappingRepository.save(companyUserMapping);

Here If I try to get Company details by Id, there is repeated information and also unwanted company information which is associated to few common users.The output Json is as below

{
    "companyId": 1,
    "companyName": "ABC company",
    "companyUsers": [
        {
            "companyUserMappingId": 1,
            "company": 1,
            "user": {
                "userId": 1,
                "email": "sachintendulkar@gmail.com",
                "companyUserMapping": [
                    1
                ]
            },
            "active": true,
            "external": false
        },
        {
            "companyUserMappingId": 3,
            "company": 1,
            "user": {
                "userId": 3,
                "email": "shanewarne@gmail.com",
                "companyUserMapping": [
                    3,
                    {
                        "companyUserMappingId": 4,
                        "company": {
                            "companyId": 2,
                            "companyName": "XYZ company",
                            "companyUsers": [
                                {
                                    "companyUserMappingId": 2,
                                    "company": 2,
                                    "user": {
                                        "userId": 2,
                                        "email": "sehwag@gmail.com",
                                        "companyUserMapping": [
                                            2
                                        ]
                                    },
                                    "active": true,
                                    "external": false
                                },
                                4
                            ]
                        },
                        "user": 3,
                        "active": true,
                        "external": false
                    }
                ]
            },
            "active": true,
            "external": false
        }
    ]
}

How do I get the consolidated data like below.

{
  "companyId": 1,
  "companyName": "ABC company",
  "companyUsers": [
    {
      "companyUserMappingId": 1,
      "user": {
        "userId": 1,
        "email": "sachintendulkar@gmail.com"
      },
      "active": true,
      "external": false
    },
    {
      "companyUserMappingId": 3,
      "user": {
        "userId": 3,
        "email": "shanewarne@gmail.com"
      },
      "active": true,
      "external": false
    }
  ]
}

And then if I call get User by UserId, the consolidated data should be like below.

{
  "userId": 1,
  "email": "sachintendulkar@gmail.com",
  "associatedCompany": [
    {
      "companyId": 1,
      "companyName": "ABC company"
    }
  ]
}
0 Answers
Related