I have problems with architecture of my project application. I wanted to avoid all classes being public (it is problem of layer packaging), so I created vertical packages as shown below on the screen-shot:
But I have got a problem: My User class has to be public as well as DiagnosticResult -> there is OneToMany connection between them, also UserRepository has to be public due to it's usage in DiagnosticResult service. Here is the code:
public class User extends BaseEntityAudit {
//some simple fields
@OneToMany(targetEntity = DiagnosticResult.class, mappedBy = "user", fetch = FetchType.LAZY)
private List<DiagnosticResult> resultsList = new ArrayList<>();
public class DiagnosticResult extends BaseEntityAudit {
//some simple fields
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;
class DiagnosticResultService {
private final DiagnosticResultRepository resultRepository;
private final UserRepository userRepository;
DiagnosticResult saveDiagnosticResult(DiagnosticResult result, String login) {
var retrievedUser = userRepository.findUserByLogin(login).orElseThrow(() -> new EntityNotFoundException("User with login: " + login + " does not exist in database."));
result.setUser(retrievedUser);
retrievedUser.getResultsList().add(result);
userRepository.save(retrievedUser);
return resultRepository.save(result);
}
What is my problem? I heard that good practice is to make as many as possible classes package-private. I know how to make it - by putting diagnose classes with user classes together - but I don't want to do that. It will decrease readability plus in the future I want to learn microservices so it must be in different packages.
What can I do to make classes: User, UserRepository, DiagnosticResult package-private, but not moving them to the same package? Or maybe my packaging is wrong and it should be together? Can you give me any advice?
ps:For now I havent got facade classes but I will make them, I also heard that if enything from package must be public it is only facade and dto -> so maybe this is the clue to my architecture, but still how to make User and DiagnosticResult package-private?