Mapping domain entities using JPA

Previously, we created a Person POJO class that we used to illustrate some examples using the CDI. Let's now consider the same POJO again, with some additional fields.

Let's say we want to map this class to a table in a relational database:

class Person : Identity() {
var preferredLanguage: PreferredLanguage? = null
lateinit var identifier: UUID
lateinit var name: PersonName
lateinit var loginId: String
lateinit var address: Address
}

In order to map this POJO class to a table in the database, we need to annotate the class with @Entity. This makes this class identifiable to business domain entities:

@Entity
class Person : Identity() {
var preferredLanguage: PreferredLanguage? = null
lateinit var identifier: UUID
lateinit var name: PersonName
lateinit var loginId: String
lateinit var address: Address
}
The @Entity annotation can only be specified at the type level; not at the field or the function level.

Each table in a database will have one or more primary keys in it to uniquely identify a record in the table. We have to specify one or more properties that act as an identifier in the entity. For this, we need to annotate the property with the @Id annotation. This makes our business entity identifiable.

For example, the identifier field in our Person entity can be marked with @Id, as each ID will be different in the business context. This is shown in the following code:

@Entity
class Person : Identity() {
@Id
lateinit var identifier: UUID
lateinit var name: PersonName
lateinit var loginId: String
lateinit var address: Address
var preferredLanguage: PreferredLanguage? = null
}
In Java, we can annotate setters and getters in the entity class. 

All of the properties are automatically mapped to table columns in the database. We can also annotate other properties of the entity class as follows:

     @Id
public void setIdentifier(UUID uuid){
this.identifier = uuid;
}
In Kotlin, we don't have setters as the member fields are accessible directly.

We can also specify the table name to which our entity mapped using the @Table annotation. For example, let's say a person is a table in the database. To map the Person entity to this table, we can use @Table by specifying the name attribute with the table name in it, which is shown in the following code:

@Table(name = "person")
@Entity
class Person : Identity() {
@Id
lateinit var identifier: UUID
lateinit var name: PersonName
lateinit var loginId: String
lateinit var address: Address
var preferredLanguage: PreferredLanguage? = null
}

If the @Table annotation is not mentioned in our entity class, or if it is mentioned without the name attribute supplied, the table name defaults to the name of the entity.

To interact with the database using the entity from our data access object (DAO) layer or façade, we use the functionality that comes with the JPA, called EntityManager.

In previous examples, we used IdentityRepository to store the person object. Since we now have the EntityManager JPA, we don't need this repository bean:

@Stateless
class App {
@Inject
private lateinit var identityCreator: IdentityCreator
@PersistenceContext
private lateinit var entityManager: EntityManager

fun createIdentity(identity: Identity): Identity {
val person = identityCreator.createPerson(identity)
entityManager.persist(person)
return person
}
}

We acquire the EntityManager with the @PersistenceContext annotation that will be used to interact with the persistence unit of our application. We use the persist method of the EntityManager to store our entity in the database.

Our createIdentity() function will be executed within the transaction, which means the person data is committed to the database only after the createIdentity() function finishes its execution.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset