For each strongly associated group of entities, create a package. For example, there will be a package with the property entities. There will be another package with the HR entities. There is no single problem in a package depending on several others that depend on several others, what happens is that this can attract other problems. The main problems are:
-
Package A depends on Package B, which in turn depends on Package A. Cyclic dependencies are horrible things that no one deserves. The existence of a cyclic dependency may indicate that packets A and B should be one or that there is something wrong in their architecture. Never accept having a cyclical dependency and always try to eliminate them as soon as possible.
Package A depends on package B that depends on package C, but package C is a dead weight and useless for A. In this case it means that package B is bloated, and possibly it is the case of dividing in smaller packages.
What you have to keep in mind are the rules of encapsulation, low coupling and high cohesion, which are more or less the same as those that apply with classes.
Prefer to use a resource architecture (REST) or services (SOA) if possible. For example, in the HR database, the mover should be just HR, as this is the system that concentrates HR business knowledge and its database is part of this knowledge. Thus, other systems that need some information from HR should invoke the HR service to do their jobs, and never access the database directly. Note that this is nothing more than the encapsulation concept applied at a higher level. Accessing the database from another system is a way of violating the encapsulation of this other system. And one of the benefits of encapsulation is the control of access (and sanity and maintainability) of private data. At this point, your service will also be the equivalent of an interface. If you make sure that each application only messes with your database, you can prevent any changes that are required over time in a system's database from causing side effects on other systems.
One way to reduce the coupling is by interfaces that separate the implementation specification. This, coupled with the services or features architecture, allows you to drastically reduce your dependencies. Instead of depending on a class truck that changes the database of another system, you only depend on an interface for this other system and a stub implementation of this system. Stubs are nothing more than implementations of these interfaces that make their remote calls. If you prefer to use EJB (it is not necessary, but it is an alternative), you probably will not need to create stubs , as EJB already takes care of it. Another simple alternative is RMI, but I would recommend using JSON with Servlets or JAX-RS.
One way to increase cohesion is to ensure that your packages are not too large, with features that should not belong to them and not too small, with features missing or delegated to customers. If they are too large (it may be a good idea to split them into smaller packages). If they are too small (or to use a more precise term, anemic), then it may be that you have separated things that should not be separated.