@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); } }
@EmbeddedId public CustomerPK getPk() { return pk; }
The CustomerPK class is mapped to Customer just like any other embeddable object. The additional @EmbeddedId annotation specifies that it will be the primary key. NOTE: If you provide a primary key class, JBoss cannot autogenerate the key for you. You must allocate a CustomerPK class and instantiate it with your id and name when you create the Customer.
@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 );
Unix: $ export JBOSS_HOME=<where your jboss 4.0 distribution is> Windows: $ set JBOSS_HOME=<where your jboss 4.0 distribution is> $ ant $ ant run run: [java] 2004-10-07 14:39:23,103 INFO org.jboss.remoting.InvokerRegistry[main] - Failed to load soap remoting transpo rt: org/apache/axis/AxisFault [java] Air France customers [java] Bill [java] Monica [java] USAir customers [java] Molly
The INFO message you can ignore. It will be fixed in later releases of JBoss 4.0.