You are totally free to organise your code however you wish. This is unrelated to hexagonal architecture.
With that being said, if you want to use hexagonal architecture efficiently, you should probably follow a domain-driven design, that is to say, you should organise your code based on domain/business logic, and not based on technical similarities.
For example, instead of having the following structure:
controller
product
cart
customer
service
product
cart
customer
repository
product
cart
customer
DDD recommends the following structure:
product
controller
service
repository
cart
controller
service
repository
customer
controller
service
repository
Once you've done this, if it helps, you could wrap these in three packages for the differents parts of the hexagonal architecture: user side, business logic and server side. This is something I've done in the past; it helps me keep the different layers clear.
userside
product
controller
cart
controller
customer
controller
businesslogic
product
service
cart
service
customer
service
serverside
product
service
cart
repository
customer
repository
Again, the structure of your packages is not the most important concept. The hexagonal architecture focuses on three principles:
- Explicitly separate user side, business logic, and server side layers. A clear package structure helps, but you can separate these layers in other ways.
- Dependencies go from user side and server side layers to the business logic. This is done by defining interfaces and adapters in the business logic (see below). The goal is that code in the user side and server side may be changed without impacting the business logic layer. For example, if you wish to change your repository from a MySQL implementation to a PostgreSQL implementation (in the server side layer), this change should not impact your business logic: the new implementation need only comply with the interface in the business logic.
- Dependency injection: the business logic defines interfaces (commonly called "ports") and transformers ("adapters") with which the user side and server side layers must comply for communication.
It's a very DDD oriented architecture; the idea is that the business logic remain as close to the domain as possible, and unadulterated by technical requirements.