3. Object-Oriented Databases
1. OO Databases. ObjectDB
In this section, as DBMS, ObjectDB has been chosen, since it is very versatile, free and even allows it to be embedded within our Java projects, which allows great simplicity for the development of small applications, due to the elimination of a server
2. Installation
ObjectDB does not require installation as such, since all its code is integrated into an API for accessing the database packaged in a jar file. From the official website we can download the ObjectDB Development Kit. At the time of writing this book, the version is 2.9.0. This kit contains, among others:
- Dependencies for Java projects
- Utilities for viewing and consulting the database
- Server for distributed applications
- Documentation
Once unzipped, we will only need the Java virtual machine installed on our system to run all the elements. To use ObjectDB in our project we must add the objectdb.jar file to our project dependencies or do it using the maven or gradle dependency manager.
At this moment we can connect to the database, the centralization of the connection to the database is done through an instance of an EntityManagerFactory object, from which we can obtain several instances of an EntityManager.
From the EntityManager we will be able to carry out the typical CRUD operations, taking into account that whenever there are modifications in it. We must carry out the operation within a transaction to avoid inconsistent situations in it. Here we see a possible class with establishing the connection and getting an EntityManager. This code can be seen in the attached file ConexionOBD.java. Notice that import are from javax.persistence:
3. Persisting classes
To persist an object, we will need (regarding Hibernate):
- Annotate your class and mark it as
@Entity - Define a field as
@Idand optionally auto-increment with@GeneratedValue. - The rest of the entity's attributes, by default, are automatically persisted without any type of annotation. In case of not wanting to persist any, we can indicate it with
@Transient.
| Java | |
|---|---|
To store a Alumno, it will suffice to create an Alumno and persist it in the database, as seen below, assuming the object with type conexionDB seen in the attached file:
| Java | |
|---|---|
** Embedded classes or Components**
In Java there are sometimes classes that do not have their own existence, unless they exist inside another class such as an Address class. It doesn't make sense to create an ad-hoc Address object, instead it does make sense to create it so that an Address exists, for example inside a Student.
For these (weak) cases that exist embedded within other classes, we must declare them as embeddable using the @Embeddable annotation and mark them as embedded (@Embedded) within the class that they exist.
| Java | |
|---|---|
An Alumno entity will be stored in the database, but the Direccion does not exist as an object itself.
4. Relationships
4.1. One-to-one relation
The simplest relation is one-to-one, in which one object contains another object. We will mark it as we already did in Hibernate with the @OneToOne modifier indicating that the saving is cascaded (cascade=CascadeType.PERSIST)
From now on, when you save an instance of an object, your own instance of the related object will be saved and linked. The linked object will have existence in itself (if it is marked as @Entity). A basic example that a class has a single Tutor:
Based on an example that a Clase (of an institute) has a Tutor associated, the example will be the following:
| Java | |
|---|---|
Attention
Remember that, in the same way as hibernate, this relation is unidirectional, but can be done bidirectional
4.2. One-to-many relation
We are now going to refer to a classic relationship in which a Profesor is the tutor of several Alumno. These relationships can be one-way or two-way. In this example we will see it bidirectional, in such a way that given a student we can know who is his tutor and given a teacher we can obtain the students he tutors.
| Java | |
|---|---|
Attention
Remember that, in the same way as hibernate, loading the collections could be done immediately, with an EAGER way or when is needed in LAZY mode.
4.3. Many-to-many
In many-to-many relationships we can approach them in various ways. Let us give the example of teaching between Profesor and Alumno. If we simply want to indicate who teaches whom, it would sufficient to store a collection of teachers in each student (the teachers who teach that student), and symmetrically, in each teacher a collection of students (the students to whom they teach). class. In this case, it would be bidirectional, since from one class we can navigate to the other, thus remaining:
| Java | |
|---|---|
Attention
If we need to save any information within said relationship, such as the grade that has been received, the student, or the incidents posted, etc. then we must create a new class, which will incorporate the attributes of the relationship, and make one-to-may relationships from each entity (Student/Teacher) to the new entity (Teaching). This assumption is the famous N-M relations generate a table with the attributes they possess of the relational model.
5. Queries
We are going to review how we can load the data that we have previously saved in the database. Suppose we have a Student class, mapped with an entity and with an identifier (idStudent). The easiest way to load a Student, knowing its id, is the find(class,id) method, as we did in Hibernate:
| Java | |
|---|---|
The rest of the loads must be carried out through queries, in a JPQL language (Java Persistence Query Language), again similar to Hibernate's HQL.
There are two classes: Query and TypedQuery (the second one inherits from the first one), which are usually used in the first case when we don't know the result of the query, and in the second when we know the result.
The first one is polymorphic, so it will dynamically link the results, and the second one verifies the result with the current class. The official documentation recommends the use of the second one, TypedQuery for queries and Query for updates and deletions.
Regarding same as hibernate, we can ask the database as follows:
| Java | |
|---|---|
or with parameters:
| Java | |
|---|---|
or create a specific named queries:
5.1. Delete and Update
Finally, we are going to review the last CRUD operations that we have left. The updates are totally transparent to the user, since any modification that is made within the context of a transaction will be automatically saved when closing it with a commit(). Alternatively, update Queries can be performed
For deletes, if the object has been retrieved from the database, and is therefore in the current transaction, it can be removed with em.remove(object). It will be deleted from the database when the commit is made.