Primary Key
With generator:
class Person {
private long personId;
...
}
<id name="personId"
type="long"
column="PERSONID"
unsaved-value="-1">
<generator class="native"/>
</id>
- different generators?
- what about composite keys?
Plain Old Properties
Primitive or String field:
class Person {
...
private String lastName;
...
}
<property name="lastName"
type="string"
column="LASTNAME"/>
</property>
<property name="name"
type="string">
<column name="NAME"
not-null="true"
length="255"
unique-key="UNIQUE_NAME_AT_LEVEL"/>
</property>
- not-null: get hibernate exception if null when saving
- what is unique-key for?
Recursive parent-child relationship
| class Person { private int personId; ... private Person parent; private Set children; ... } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... PARENT_ID INTEGER; ... ) |
| <class name="org.demo.Person" table="PERSON"> ... <many-to-one name="parent" cascade="none"> <column name="PARENT_ID" not-null="false"/> </many-to-one> <set name="children" cascade="all-delete-orphan" inverse="true" lazy="true" batch-size="10"> <key column="PERSON_ID"/> <one-to-many class="Person"/> </set> ... </class> |
- what is outer-join ???
- what is foreign-key ???
- what is cascade-delete-orphan ???
- how does the inverse work ???
- how does batch-size work ???
Many-to-one relationships
First, with uni-directional navigation
| class Person { private int personId; ... private Country country; ... } | class Country { private int countryId; ... } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... COUNTRY_ID INTEGER; ... ) | CREATE TABLE COUNTRY ( COUNTRY_ID INTEGER PRIMARY KEY; ... ) |
| <class name="org.demo.Person" table="PERSON"> ... <many-to-one name="country" column="COUNTRY_ID" class="org.demo.Country" not-null="true"/> ... </class> | <class name="org.demo.Country" table="COUNTRY"> ... </class> |
Now, with bi-directional navigation:
| class Person { private int personId; ... private Country country; ... } | class Country { private int countryId; ... private Set citizens; ... } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... COUNTRY_ID INTEGER; ... ) | CREATE TABLE COUNTRY ( COUNTRY_ID INTEGER PRIMARY KEY; ... ) |
| <class name="org.demo.Person" table="PERSON"> ... <many-to-one name="country" column="COUNTRY_ID" class="org.demo.Country" not-null="true"/> ... </class> | <class name="org.demo.Country" table="COUNTRY"> ... <set name="citizens" inverse="true" cascade="save-update"> <key column="COUNTRY_ID"/> <one-to-many class="org.demo.Person"/> </set> ... </class> |
One-to-one relationships
First, uni-directionally:
| class Person { private int personId; ... private Address address; ... } | class Address { private int addressId; ... } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... ADDRESS_ID INTEGER; ... ) | CREATE TABLE ADDRESS ( ADDRESS_ID INTEGER PRIMARY KEY; ... ) |
| <class name="org.demo.Person" table="PERSON"> ... <many-to-one name="address" column="ADDRESS_ID" class="org.demo.Address" cascade="save-update" unique="true"/> ... </class> | <class name="org.demo.Address" table="ADDRESS"> ... </class> |
Secondly, bi-directionally:
| class Person { private int personId; ... private Address address; ... } | class Address { private int addressId; ... private Person person; } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... ADDRESS_ID INTEGER; ... ) | CREATE TABLE ADDRESS ( ADDRESS_ID INTEGER PRIMARY KEY; ... ) |
| <class name="org.demo.Person" table="PERSON"> ... <many-to-one name="address" column="ADDRESS_ID" class="org.demo.Address" cascade="save-update" unique="true"/> ... </class> | <class name="org.demo.Address" table="ADDRESS"> ... <one-to-one name="person" class="org.demo.Person" property-ref="address"/> ... </class> |
Many-to-many associations
Requires a join table.
First, uni-directionally:
| class Person { private int personId; ... } | class Project { private int projectId; ... private Set participants; ... } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... ) | CREATE TABLE PROJECT ( PROJECT_ID INTEGER PRIMARY KEY; ... ) |
| CREATE TABLE PROJECT_PERSON ( PROJECT_ID INTEGER; PERSON_ID INTEGER; ... ) | |
| <class name="org.demo.Person" table="PERSON"> ... </class> | <class name="org.demo.Project" table="PROJECT"> ... <set name="participants" table="PROJECT_PERSON" lazy="true" cascade="save-update"> <key column="PROJECT_ID"/> <many-to-many class="Person" column="PERSON_ID"/> </set> ... </class> |
How about bi-directional?
| class Person { private int personId; ... private Set project; ... } | class Project { private int projectId; ... private Set participants; ... } |
| CREATE TABLE PERSON ( PERSON_ID INTEGER PRIMARY KEY; ... ) | CREATE TABLE PROJECT ( PROJECT_ID INTEGER PRIMARY KEY; ... ) |
| CREATE TABLE PROJECT_PERSON ( PROJECT_ID INTEGER; PERSON_ID INTEGER; ... ) | |
| <class name="org.demo.Person" table="PERSON"> ... <set name="projects" table="PROJECT_PERSON" lazy="true" inverse="true" cascaded="save-update"> <key column="PERSON_ID"/> <many-to-many class="ord.demo.Project" column="PROJECT_ID"/> </set> ... </class> | <class name="org.demo.Project" table="PROJECT"> ... <set name="participants" table="PROJECT_PERSON" lazy="true" cascade="save-update"> <key column="PROJECT_ID"/> <many-to-many class="org.demo.Person" column="PERSON_ID"/> </set> ... </class> |