4.2.3.2. Many-to-Many Association with Link Entity
The many-to-many association is always implemented using a joining table, but creating an entity to reflect this table is optional. The joining entity can be created in case you want to store some additional fields in the joining table.
Let’s demonstrate this approach using the Airport
and the DutyFree
entities as an example. Many different duty-free shops can be located in one airport, and one duty-free shop can be represented in many different airports. Suppose that we want to store the link airport-shop and the currency used in this shop and this airport:
-
Airport.java - the
Airport
entity contains a one-to-many composition ofAirportDutyFree
instances.In the Studio entity designer, set for the
dutyFreeShops
attribute: Attribute type -COMPOSITION
, Cardinality -ONE_TO_MANY
.@Composition @OnDelete(DeletePolicy.CASCADE) @OneToMany(mappedBy = "airport") protected List<AirportDutyFree> dutyFreeShops;
-
DutyFree.java - the
DutyFree
entity contains a one-to-many composition ofAirportDutyFree
instances, too.In the Studio entity designer, set for the
airports
attribute: Attribute type -COMPOSITION
, Cardinality -ONE_TO_MANY
.@Composition @OnDelete(DeletePolicy.CASCADE) @OneToMany(mappedBy = "dutyFree") protected List<AirportDutyFree> airports;
-
AirportDutyFree.java - thus, the
AirportDutyFree
entity contains two many-to-one references:airport
anddutyFree
.@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "AIRPORT_ID") protected Airport airport; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "DUTY_FREE_ID") protected DutyFree dutyFree; @Column(name = "CURRENCY") protected Integer currency;
-
views.xml - the
airport-duty-free
view of the airport editing screen contains the composition ofdutyFreeShops
(referencing theAirportDutyFree
joining entity) withdutyFree
andcurrency
attributes.The
dutyFree-airport
view follows the same logic: it includes the composition ofairports
(referencing theAirportDutyFree
joining entity) withairport
andcurrency
attributes. -
duty-free-edit.xml - the XML descriptor of the duty-free shop editor defines a datasource for the
DutyFree
instance and a nested one for its airports. It also contains a table displaying airports and the custom action to pick an airport directly, bypassing theAirportDutyFree
editor.
As a result, editing of a DutyFree
instance works as follows:
The DutyFree
edit screen shows a list of airports and the currency drop-down.
A user can click Add airport, the Airport
lookup will be opened, and the user can either select an airport to add or open its editor. When the user selects an airport, the new AirportDutyFree
instance is created with the default currency. This instance it is not saved to the database, but added to the airportsDs
datasource of the DutyFree
editor.
When OK is clicked in the Airport
editor, the updated instance of the airport is saved both to the database and to the airportsDs
datasource of the DutyFree
editor, as the Airport
entity is fully independent.
The user can create new airports and delete existing ones, and all changes will be saved to the database in separate transactions and to the airportsDs
datasource as well.
When a user clicks OK in the duty-free edit screen, the updated DutyFree
instance together with all the updated AirportDutyFree
instances is submitted to the DataManager.commit() method on the middleware and saved to the database within a single transaction.