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"
}
]
}