JBoss.org Community Documentation
The EJB 3.0 specification allows you to define a primary key class as a @Embeddable
and use it as the
primary key of your Entity bean. One or more properties can be used as members of the primary key for that particular table.
This tutorial is an adaptation of the "relationships" tutorial. It adds a primary key class to Customer that holds both
the name
and id
of the Customer.
@Embeddable public class CustomerPK implements java.io.Serializable { private long id; private String name; public CustomerPK() { } public CustomerPK(long id, String name) { this.id = id; this.name = name; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int hashCode() { return (int) id + name.hashCode(); } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof CustomerPK)) return false; if (obj == null) return false; CustomerPK pk = (CustomerPK) obj; return pk.id == id && pk.name.equals(name); } }
Open up org.jboss.tutorial.composite.bean.Customer
and look for the getPk()
method.
This defines the primary key class.
@EmbeddedId public CustomerPK getPk() { return pk; }
The org.jboss.tutorial.composite.bean.CustomerPK
class is mapped to
org.jboss.tutorial.composite.bean.Customer
just like any other embeddable object.
The additional @EmbeddedId
annotation specifies that it will be the primary key.
If you provide a primary key class, JBoss cannot auto-generate the key for you. You must allocate a CustomerPK class and instantiate it with your id and name when you create the Customer.
There is a many-to-many relationship between org.jboss.tutorial.composite.bean.Customer
and
org.jboss.tutorial.composite.bean.Flight
. In order to have a many-to-many relationship there
needs to be a distinct join table that maps the many-to-many relationship. This is called an association table.
You need to use the @JoinTable
annotation to define this join table. The @JoinTable
must be defined on both sides of the bi-directional relationship. Let's look at the Customer side of the relationship
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER, mappedBy="customers") @JoinTable(name="flight_customer_table", joinColumns={@JoinColumn(name = "FLIGHT_ID")}, inverseJoinColumns={@JoinColumn(name = "CUSTOMER_ID"), @JoinColumn(name = "CUSTOMER_NAME")}) public Set<Flight> getFlights() { return flights; }
The mappedBy
attribute specifies which side of the relationship is responsible for managing the relationship.
If it is not set, then that side is responsible. So, for this example, the Flight
Entity is responsible
for managing the relation. In this example, we are specifying multiple inverseJoinColumns
because Customer has a composite primary key.
Let's look at the other side of the relationship in Flight:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER) @JoinTable(name = "flight_customer_table", joinColumns = {@JoinColumn(name = "FLIGHT_ID")}, inverseJoinColumns = {@JoinColumn(name = "CUSTOMER_ID"), @JoinColumn(name = "CUSTOMER_NAME")}) public Set<Customer> getCustomers() { return customers; }
The Flight
Entity must also define the @ManyToMany
and @JoinTable
.
The database associate table will look like this:
create table FLIGHT_CUSTOMER_TABLE ( CUSTOMER_ID integer, CUSTOMER_NAME varchar, FLIGHT_ID integer );
To build and run the example, make sure you have installed JBoss 5.x. See the Section 1.1, “JBoss Application Server 5.x” for details.
From the command prompt, move to the "composite" folder under the Section 1.3, “Set the EJB3_TUTORIAL_HOME”
Make sure your JBossAS-5.x is running
$ ant $ ant run run: [java] Air France customers [java] Bill [java] Monica [java] USAir customers [java] Molly
$ mvn clean install -PRunSingleTutorial
You can view the tables created by JBoss by going to the
Hypersonic Service,
scrolling down to the startDatabaseManager
button and clicking it.
A Hypersonic SQL window will be minimized, but you can open it up to look at the tables and do queries.