How to make relation between entities from different packages and keep encapsulation?

87 views Asked by At

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:

packages 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?

0

There are 0 answers