Problem summary
I am getting unrelated data from the Many-to-Many With a New Entity concept for the first two cases.
- Fetching a particular company and associated users of the company.
- Fetching particular user and associated company.
- Not able to feth company and user whose company status is not equal to 3 (CompanyStatus=1 "Pending" ,CompanyStatus=2 "Other",CompanyStatus=1 "Active")
To work on this Many-to-Many With a New Entity concept I have used Company, User, and CompanyUserMapping as an entity.
The blog that I have referred https://www.baeldung.com/jpa-many-to-many section 4.2
As mentioned above I have created Company, User, and CompanyUserMapping as below
Company
@Getter
@Setter
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long companyId;
private String companyName;
private String companyDescription;
private String companyWebsite;
private String companyEmailDomain;
private Integer companyTypeID;
private Integer numberOfEmployeesID;
private String companyLogo;
private Integer companyStatus;
private Boolean active;
@OneToMany(mappedBy = "company",fetch = FetchType.EAGER)
Set<CompanyUserMapping> companyUserMapping;
}
User
@Getter
@Setter
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long userId;
private String firstName;
private String lastName;
private String email;
private String encryptedEmail;
private String username;
private String password;
private String userStatus;
private String guid;
private Boolean isNotlocked;
private Date lastLogin;
private String profilePic;
@OneToMany(mappedBy = "user",fetch = FetchType.EAGER)
Set<CompanyUserMapping> companyUserMapping;
}
CompanyUserMapping
@Getter
@Setter
@Entity
public class CompanyUserMapping {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long companyUserMappingId;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "company_id")
private Company company;
@ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
private String role;
private String [] authorities;
private boolean isExternal;
private boolean isActive;
private Long customerId;
}
Then I inserted two companies and a user in each of them. Then I have also inserted a common user for both of the companies.
{
"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
}
]
}
In the above JSON, ABC and XYZ are two companies and a common user for both of the companies is shanewarne@gmail.com
As mentioned in the summary If I try to pull a particular company(ABC company) and associated users, it also brings another company and users which is unrelated.
To resolve this problem I have Implemented like below
public CompanyDto getConsolidatedCompanyData(Long companyId) {
Company existingCompany = companyRepository.findById(companyId).orElseThrow(() -> new ResourceNotFoundException("Company not found for the companyId :: "+companyId));
CompanyDto companyDto=new CompanyDto();
companyDto.setCompanyId(existingCompany.getCompanyId());
companyDto.setCompanyName(existingCompany.getCompanyName());
Set<CompanyUserMappingDto> companyUserMappingDtoList=new LinkedHashSet<>();
Set<CompanyUserMapping> companyUserMappingList=existingCompany.getCompanyUserMapping();
for (CompanyUserMapping cum : companyUserMappingList) {
CompanyUserMappingDto companyUserMappingDto=new CompanyUserMappingDto();
companyUserMappingDto.setCompanyUserMappingId(cum.getCompanyUserMappingId());
CompanyUserDto cdto=new CompanyUserDto();
cdto.setUserId(cum.getUser().getUserId());
cdto.setEmail(cum.getUser().getEmail());
companyUserMappingDto.setUser(cdto);
companyUserMappingDto.setActive(cum.isActive());
companyUserMappingDto.setExternal(cum.isExternal());
companyUserMappingDtoList.add(companyUserMappingDto);
}
companyDto.setAssociatedUsers(companyUserMappingDtoList);
return companyDto;
}
In the same way, if I try to fetch a particular user and associated company I am getting related data so I have implemented code
private UserDto getConslidatedUserData(Long userId) {
User existingUser = userRepository.findById(userId).orElseThrow(() -> new ResourceNotFoundException("User not found for the userId :: "+userId));
Set<UserCompanyMappingDto> associatedCompanies=new HashSet<>();
UserDto userDto=new UserDto();
userDto.setUserId(existingUser.getUserId());
userDto.setEmail(existingUser.getEmail());
Set<CompanyUserMapping> companyUserMapping=existingUser.getCompanyUserMapping();
for (CompanyUserMapping companyUserMapping2 : companyUserMapping) {
UserCompanyMappingDto userCompanyMappingDto=new UserCompanyMappingDto();
userCompanyMappingDto.setCompanyUserMappingId(companyUserMapping2.getCompanyUserMappingId());
UserCompanyDto userCompanyDto=new UserCompanyDto();
userCompanyDto.setCompanyId(companyUserMapping2.getCompany().getCompanyId());
userCompanyDto.setCompanyName(companyUserMapping2.getCompany().getCompanyName());
userCompanyMappingDto.setCompany(userCompanyDto);
associatedCompanies.add(userCompanyMappingDto);
}
userDto.setAssociatedCompanies(associatedCompanies);
return userDto;
}
Do I need to improvise Implementation for the first two cases?