3. Entities
1. Mapping Entities. Beans
Once we have studied the project configuration and setup, it is time to start to map our entities and relationships. Starting with the relational model, we are going to use next entity Peli, based on:
| SQL | |
|---|---|
You can find it in the resource folder in a DBCine1.sql script. The class to encapsulate this entity looks like:
Tip
Remember that you can use Lombook library to create beans in a faster way.
2. Mapping files
The bean created in last section cannot be persisted yet. In order to do it, we must create an external file to the class, with the extension hbm.xml and with the same name as the class (Hibernate Mapping). The file location does not matter, but it is a good idea to save the model classes on one side and the mapping files on the other.
So we will create an orm package and within it, we will create the Peli.hbm.xml file. Let's go to explain it by example, because syntax is pretty big.
We point on basics:
- Lines 1-3 are xml header, pointing to the dtd file with grammar in order to check that file is well-formed.
<hibernate-mapping>\(\rightarrow\) tell that this file is a mapping<class>\(\rightarrow\) is the tag to specify what class we are mapping, and has two attributes:name="Model.Peli"\(\rightarrow\) pointer to the class (Java file), without extension.table="Peli"\(\rightarrow\) here we write the name of the table in the database who will contain the data.- It remains to say the fields in the class and its respective column. We distinguish between:
<property>\(\rightarrow\) for normal fields. It could appear several attributes:name\(\rightarrow\) (mandatory) is the name of the field inside the classcolumn\(\rightarrow\) is the name of the matching column in the table. If nocolumnis set, hibernate will suppose that it is the same asnameattribute.type\(\rightarrow\) is the java type of the column. By default, Hibernate will use the same as the specified by the class, but we must indicate to resolve ambiguous fields (look next figure, specially in Date and Time formats)
<id>\(\rightarrow\) (mandatory) is the field that will be used as primary key, and also could appear name, column and type attributes. Exists the possibility that primary key will be generated by the DBMS, and we will set how, with<generator>\(\rightarrow\) set the engine to generate primary key, that can be set in several ways. Withnativewe use the same method of the underlying database. On this tutorial you can get a full samples link
Attention
- You have to save this file to be accessed in our project. A good option is to create a
resourcesfolder insidesrc/mainand save these files inside. - Hibernate needs get/set methods in order to access fields of our objects. Nevertheless, maybe you don't want to create any methods, nut hibernate needs. The solution is to add a new attribute
access=fieldthat allows hibernate to get/set without getters and setters.
Note
We will study more options like foreign keys in next sections.
Now is time to create a little program to prove all the contents. Take a look to next code:
Comments:
- Notice than to save an Object (e.g. insert a row in the database), you only need to run
Session.save(Object). - To get one object from database, there is an easy way, knowing class and primary key of the object. Method is
Session.get(class,ID), and we get an onject of this class whit this ID. - Notice that when we create new object, it hasn't an ID (remember that is auto generated), but when we save it, a new ID was assigned.
Important
If we choose to create in hbm2ddl.auto property, as you will guess, the database will be empty. It's a good idea to create a file called imports.sql with some data needed to test our programs.
3. Mapping classes. Annotations
Before starting annotating classes, let's show that:
-
JDO (Java Data Objects) is a persistence standard developed by Apache, which includes a persistence framework based on post compilation. Although trying to achieve a more efficient technique, there are few commercial initiatives that follow this standard.
-
The alternative is JPA (Java Persistance API), a persistence standard incorporated into JDK 5, with various libraries that support it, and based on the principle of reflection, which uses metadata as well as information about the classes and the structure What a fan that the virtual machine can access the information collected from the objects to invoke their methods and build new instances. The two most widely implemented ORMs in Java: Hiberate and EJB use this standard.
Mapping classes is easy, and we only need to match every field with every column. The drawback is than we need to maintain two files: classes and mapping files. For this reason, we can join both elements, adding inside classes the specific annotations to do the match. JPA interface allow us to do this task.
Let's go to show a class with annotations, and compare with mapping files. Moreover, we will use Lombok to create the class, that use annotations too ;).
Info
Hibernate create firstly his annotations, in package org.hibenate.annotations, but from version 4, all these annotations were deprecated and we must take care, and import annotations from javax.persistence
Let's go to see main annotations, instead you will have lots of them in JPA documentation:
@Entityto focus that this class represent an entity in our database. Moreover, we must associate this entity to a@Tablewith the correct name.- To set database fields, we must use
@Column. You could specify more options, specially if the name of the column is different of field name. Take a look of next picture for more options. An interesting option is to set an auto generated value, with@GeneratedValue. If you do not setnameoption, it is supposed to be same. - To mark a field as primary key you need
@Id. In this case you do not need to set with@Column
4. Componenets
Let's go to revise a special design patters, who is aggregation. Is when we need a special entity that only make sense inside another entity, for instance a wheel did not have sense outside a car. If the entity can exist by its own, is when we use a relation, and we will study in next section.
The aggregate class is also called a component.
Info
These components is also substituted by a 1:1 relationship with an existence constraint, when in the normalization process is joined in the same table.
To create component, the aggregated class must be defined with @Embeaddable (and obviously without @Entity). This annotation says to Hibernate that the existence of these objects must be inside another objects. Inside these objects, as fields, the objects must be marked as @Embeeded. Let's go to see a sample:
A component Wheel
| Java | |
|---|---|
An aggregation CarWheel
When Hibernate creates the table, be notice that no table Wheel will be created. Against, all fields are inside CarWheel. Two last fiels are properties from Wheel class.
| SQL | |
|---|---|
Attention A problem could appear when you try to store two embedded components, for instance two addresses from an employee, because as hibernate creates fields from component class, fields name will be duplicated. In order to avoid this drawback, the solution is to rename the component class fields, as follows (inside the aggregate class):
| Java | |
|---|---|
Notice that:
- First embedded field do not need nothing special.
- In second, we most override the attribute names, starting an
@AttributeOverrideswith several@AttributeOverride, marking old name and new column name.
Tip
This situation is not usual, but is important to solve it when you need it.
5. Exercise
Do the following task:
- Create a maven project and add all the dependencies that you need.
- Create two classes by you own, but thinking that they will be related in a future. For instance, Teacher and Topic, or Driver and Car, or Pet and Vet. At this moment you don't need to create any relation.
- Each class must have an ID, and almost 4 fields, with several data types (do not create all String fields).
- Map both classes:
- One with an external XML file.
- The other with JPA annotations.
- Create a main App when you ask the user for data and store (and save) in the same database