Enterprise Java Development@TOPIC@
This chapter will take you through mapping a single class to multiple tables. We will reuse the example from the embedded object mapping case because conceptually they are trying to do the same thing except
In the embedded object case we had a single table and multiple objects
In this case we have multiple tables and a single object/class
In the embedded object case, our child objects did not have a primary key
In this case our child objects are entities with a primary key that are joined with the primary object's primary key.
package myorg.entityex.annotated;
import javax.persistence.*;
@Entity
@Table(name="ENTITYEX_BEAR2")
public class Bear2 {
@Id @GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
private String firstName;
private String lastName;
private int streetNumber;
private String streetName;
private String city;
private String state;
public int getId() { return id; }
public Bear2 setId(int id) { this.id = id; return this; }
public String getFirstName() { return firstName; }
public Bear2 setFirstName(String firstName) {
this.firstName = firstName; return this;
}
public String getLastName() { return lastName; }
public Bear2 setLastName(String lastName) {
this.lastName = lastName; return this;
}
public int getStreetNumber() { return streetNumber; }
public Bear2 setStreetNumber(int streetNumber) {
this.streetNumber = streetNumber; return this;
}
public String getStreetName() { return streetName; }
public Bear2 setStreetName(String streetName) {
this.streetName = streetName; return this;
}
public String getCity() { return city; }
public Bear2 setCity(String city) {
this.city = city; return this;
}
public String getState() { return state; }
public Bear2 setState(String state) {
this.state = state; return this;
}
}
Add the new entity class to your persistence unit
<class>myorg.entityex.annotated.Bear2</class>
create table ENTITYEX_BEAR2 ( id integer generated by default as identity, city varchar(255), firstName varchar(255), lastName varchar(255), state varchar(255), streetName varchar(255), streetNumber integer not null, primary key (id) );
Define a secondary table to host the name properties
@Entity
@Table(name="ENTITYEX_BEAR2")
@SecondaryTables({
@SecondaryTable(name="ENTITYEX_BEAR2_NAME")
})
public class Bear2 {
Assign the firstName and lastName properties to the secondary table.
@Column(table="ENTITYEX_BEAR2_NAME", name="FIRST_NAME", length=16)
private String firstName;
@Column(table="ENTITYEX_BEAR2_NAME", name="LAST_NAME", length=16)
private String lastName;
create table ENTITYEX_BEAR2 ( id integer generated by default as identity, city varchar(255), state varchar(255), streetName varchar(255), streetNumber integer not null, primary key (id) ); create table ENTITYEX_BEAR2_NAME ( FIRST_NAME varchar(16), LAST_NAME varchar(16), id integer not null, primary key (id) ); ... alter table ENTITYEX_BEAR2_NAME add constraint FKED0C2F35D7F6CC81 foreign key (id) references ENTITYEX_BEAR2;
Add a second secondary table for the address properties
@Entity
@Table(name="ENTITYEX_BEAR2")
@SecondaryTables({
@SecondaryTable(name="ENTITYEX_BEAR2_NAME"),
@SecondaryTable(name="ENTITYEX_BEAR2_ADDRESS")
})
public class Bear2 {
Assign the address properties to the new table
@Column(table="ENTITYEX_BEAR2_ADDRESS", name="STREET_NUMBER", length=16)
private int streetNumber;
@Column(table="ENTITYEX_BEAR2_ADDRESS", name="STREET_NAME", length=16)
private String streetName;
@Column(table="ENTITYEX_BEAR2_ADDRESS", name="CITY", length=16)
private String city;
@Column(table="ENTITYEX_BEAR2_ADDRESS", name="STATE", length=16)
private String state;
create table ENTITYEX_BEAR2 ( id integer generated by default as identity, primary key (id) ); create table ENTITYEX_BEAR2_ADDRESS ( CITY varchar(16), STATE varchar(16), STREET_NAME varchar(16), STREET_NUMBER integer, id integer not null, primary key (id) ); create table ENTITYEX_BEAR2_NAME ( FIRST_NAME varchar(16), LAST_NAME varchar(16), id integer not null, primary key (id) ); ... alter table ENTITYEX_BEAR2_ADDRESS add constraint FKD1DF32EAD7F6CC81 foreign key (id) references ENTITYEX_BEAR2; alter table ENTITYEX_BEAR2_NAME add constraint FKED0C2F35D7F6CC81 foreign key (id) references ENTITYEX_BEAR2;
@Test
public void testMultiTableMapping() {
log.info("testMultiTableMapping");
Bear2 bear = new Bear2()
.setFirstName("Yogi")
.setLastName("Bear")
.setStreetNumber(1)
.setStreetName("Picnic")
.setCity("Jellystone Park")
.setState("???");
em.persist(bear);
//flush to DB and get a new instance
em.flush(); em.detach(bear);
Bear2 bear2 = em.find(Bear2.class, bear.getId());
assertEquals("unexpected firstName", bear.getFirstName(), bear2.getFirstName());
assertEquals("unexpected lastName", bear.getLastName(), bear2.getLastName());
assertEquals("unexpected street number",
bear.getStreetNumber(), bear2.getStreetNumber());
assertEquals("unexpected street name",
bear.getStreetName(), bear2.getStreetName());
assertEquals("unexpected city",
bear.getCity(), bear2.getCity());
assertEquals("unexpected state",
bear.getState(), bear2.getState());
}
-testMultiTableMapping Hibernate: insert into ENTITYEX_BEAR2 (id) values (null) Hibernate: insert into ENTITYEX_BEAR2_ADDRESS (CITY, STATE, STREET_NAME, STREET_NUMBER, id) values (?, ?, ?, ?, ?) Hibernate: insert into ENTITYEX_BEAR2_NAME (FIRST_NAME, LAST_NAME, id) values (?, ?, ?) Hibernate: select bear2x0_.id as id8_0_, bear2x0_1_.CITY as CITY10_0_, bear2x0_1_.STATE as STATE10_0_, bear2x0_1_.STREET_NAME as STREET3_10_0_, bear2x0_1_.STREET_NUMBER as STREET4_10_0_, bear2x0_2_.FIRST_NAME as FIRST1_9_0_, bear2x0_2_.LAST_NAME as LAST2_9_0_ from ENTITYEX_BEAR2 bear2x0_ left outer join ENTITYEX_BEAR2_ADDRESS bear2x0_1_ on bear2x0_.id=bear2x0_1_.id left outer join ENTITYEX_BEAR2_NAME bear2x0_2_ on bear2x0_.id=bear2x0_2_.id where bear2x0_.id=?