|
Recently, I have made a demo application with EJB3.0 for an in-house presentation about the new EJB version. I used the OracleToplink-based implementation in the JDeveloper 10.1.3 EA release (so not the final release) and the OC4J 10.1.3 DP4
container for the run-time environment. The demo showed the attendance
how you easily use EJB3.0 to manage your persistent model and access
relational data. In this posting, I want to show how to model and
manage a many-to-many relation between two tables with EJB3.0.
The case of my demo was set up by a Player entity, a Club entity and
a ContractPeriod entity. The Player and the Club entity have a
many-to-many relation with the association entity ContractPeriod. In
other words, the data model contains all the information about which
player has played/plays for which club at a specific moment of time.
I used Oracle Database 10g Express as the underlying database. The three tables are created with the following scripts:
CREATE TABLE "CONTRACTPERIOD" ( "ID" NUMBER NOT NULL ENABLE, "PYR_ID" NUMBER NOT NULL ENABLE, "CUB_ID" NUMBER NOT NULL ENABLE, "START_DATE" DATE NOT NULL ENABLE, "END_DATE" DATE, CONSTRAINT "CONTRACTPERIOD_PK" PRIMARY KEY ("ID") ENABLE, CONSTRAINT "CONTRACTPERIOD_FK" FOREIGN KEY ("PYR_ID") REFERENCES "PLAYER" ("ID") ON DELETE CASCADE ENABLE, CONSTRAINT "CONTRACTPERIOD_FK2" FOREIGN KEY ("CUB_ID") REFERENCES "CLUB" ("ID") ON DELETE CASCADE ENABLE ) CREATE TABLE "CLUB" ( "ID" NUMBER NOT NULL ENABLE, "NAME" VARCHAR2(100) NOT NULL ENABLE, "CITY" VARCHAR2(100) NOT NULL ENABLE, "COUNTRY" VARCHAR2(100) NOT NULL ENABLE, CONSTRAINT "CLUB_PK" PRIMARY KEY ("ID") ENABLE, CONSTRAINT "CLUB_UK1" UNIQUE ("NAME", "COUNTRY") ENABLE ) CREATE TABLE "PLAYER" ( "ID" NUMBER NOT NULL ENABLE, "FIRSTNAME" VARCHAR2(30) NOT NULL ENABLE, "LASTNAME" VARCHAR2(30) NOT NULL ENABLE, "NATIONALITY" VARCHAR2(30) NOT NULL ENABLE, "BIRTHDATE" DATE NOT NULL ENABLE, CONSTRAINT "PLAYERS_PK" PRIMARY KEY ("ID") ENABLE )
Using the wizard in JDeveloper I could easily generate three basic
EJB3 entity POJOs representing the three tables in the database. The EA
release of JDeveloper 10.1.3 did not facilitate an option to
automatically generate code that define the relationships between your
entities even the EJB diagram is not supported for EJB3.0 in JDeveloper
EA 10.1.3 (also in the final release). Therefore, I have to do it all
by myself. Thanks to the persistence annotations in EJB3.0 this was not
much work. In the code-box below, I show the code fragments in each
entity bean which implements the many-to-many relation between the Club
and Player entities using ContractPeriod as the association table.
//Player@Entity@Table(name = "Player")public class Player implements Serializable{... private Collection clubs @ManyToMany(fetch=EAGER,targetEntity="nl.iteye.contractadmin.Club") @AssociationTable(table = @Table(name = "CONTRACTPERIOD") , joinColumns = {@JoinColumn(name = "PYR_ID", referencedColumnName = "ID")} , inverseJoinColumns = { @JoinColumn(name = "CUB_ID", referencedColumnName = "ID") } ) public Collection getClubs() { return clubs; } public void setClubs(Collection<Club> clubs){ this.clubs=clubs; }...}//Club@Entity@Table(name = "CLUB")public class Club implements Serializable{... private Collection players @ManyToMany(mappedBy = "clubs", fetch = EAGER, targetEntity="nl.iteye.contractadmin.Player") public Collection getPlayers() { return players; } public void setPlayers(Collection<Player> players){ this.players=players; }...}
In the code-fragment above you can see that you only have to define the relationship properties at the owning side and by using mappedBy annotation you can refer to it on the inverse side. There is also no extra code needed in the ContractPeriod entity class, the AssociationTable annotationspecifies the use of the ContractPeriod entity as the association table for this relation
|