- Java EE 8 and Angular
- Prashant Padmanabhan
- 963字
- 2021-07-02 19:22:35
Entities
To activate Java persistence on a bean class, we can use the @Entity annotation, which lets us map the bean to a database table. The identifier field denoted by @Id is used to map the primary key column of the table. The mapping of a bean to a table can be done using annotations or XML, but here we will stick to using annotations. One entity instance can be considered as representing one row of a table.
XML mapping can be used to override the values defined by annotations. This can be useful for deployment-based configuration changes without changing the code.
An entity mapping structure is shown here:

The mapping defines an entity called Task, which is mapped to a table named "task_detail". While JPA would use default names based on class and member names to map it to corresponding tables and columns, there are times when you need to handle the differences. Here, we have used the @Table annotation since our class name is Task but the table name is task_detail. Similarly, if the field names are different then we could make use of the @Column annotation. An example is as follows:
@Column(name = "last_modified")
LocalDateTime lastModified;
As of JPA 2.2, we now have support for these date/time classes:
- java.time.LocalDate
- java.time.LocalTime
- java.time.LocalDateTime
- java.time.OffsetTime
- java.time.OffsetDateTime
Prior to JPA 2.2, while there was no support for the date/time APIs, we could have still managed the conversion of LocalDate or LocalDateTime using an AttributeConverter, as shown here, which is applied automatically to all entities having such fields due to autoApply=true:
@Converter(autoApply = true)
public class LocalDateConverter
implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate entityDate) {
return (entityDate == null ? null : Date.valueOf(entityDate));
}
@Override
public LocalDate convertToEntityAttribute(Date dbDate) {
return (dbDate == null ? null : dbDate.toLocalDate());
}
}
It's now also possible to inject a bean within an AttributeConverter instance; this can be useful to fetch a configuration object which may hold the needed format or other useful information. Consider using a converter when you need to map the database representation of a value to a Java representation that can't be mapped by default.
A few common use cases could be:
- Mapping a number value such as one or zero to a Boolean field
- Encryption of password for saving and decryption during fetch
- Mapping a value to a corresponding enum type
When defining the entities, it's also common to put named queries in the entity itself, which can later be referenced when querying the database using EntityManager. An example is shown here:
@Entity
@Table(name="task_detail")
@NamedQuery(name = "Task.findById",
query = "SELECT t FROM Task t WHERE t.id = :id")
@NamedQuery(name = "Task.findByName",
query = "SELECT t FROM Task t WHERE t.name = :name")
public class Task {
// code omitted
}
This can then be referenced during querying:
TypedQuery<Task> query = em.createNamedQuery("Task.findById", Task.class);
query.setParameter("id", 1);
//With TypedQuery you don't need a cast to Task type below
query.getSingleResult().getName();
When mapping an entity to a table, it's best to use the @Table annotation, rather than changing the Entity name itself. The reasons are:
@Entity(name="tasks") class Task { ... }
em.createQuery("SELECT t FROM Task t"); // won't work
em.createQuery("SELECT t FROM tasks t"); // is correct, since we changed the entity name
You may have noticed that we didn't use the NamedQueries container annotation. Well, JPA 2.2 makes use of repeatable annotations; this means you can leave out the superfluous container annotation and just repeat the one you need, such as NamedQuery. In the previous versions, you needed to use a container annotation such as NamedQueries which would then wrap multiple NamedQuery annotations. But that's no longer needed since JPA 2.2 takes advantage of the repeatable annotation feature introduced in Java 8:

Most annotation are repeatable, such as:
- NamedStoredProcedureQuery
- NamedNativeQuery
- NamedEntityGraph
- AttributeOverride
- PersistenceContext
It's fairly common to see fields such as created, last_modified in most if not all tables in a database. When mapping such tables to entities, we can use a super class with the annotation @MappedSuperclass and define the common mapping fields and associations, which all subclasses inherit. The super class itself is not persisted and only used for field inheritance. Here's an example of that:
@MappedSuperclass
public class MappedSuperEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
@NotNull
@Size(min = 1, max = 4000)
@Column(name = "name")
protected String name;
@NotNull
@Column(name = "created")
protected LocalDateTime created;
@Column(name = "last_modified")
protected LocalDateTime lastModified;
// code omitted
}
A subclass can override the basic mappings by using the AttributeOverride annotation. Notice we have used annotations such as @Size to put further validation constraints on our bean. These are from the Bean Validation API that we looked at earlier.
When working with multiple entities, you may need to define a relationship between them. In JPA, this is done by using annotations which support bidirectional and unidirectional relations. The following four annotations can be applied on relational members of a class:
- @ManyToMany
- @ManyToOne
- @OneToMany
- @OneToOne
It's no surprise that a table in a relational database is not designed with object-oriented thinking. Often, when mapping a entity to an table, we may want to group certain fields/members and use a composition rather than declaring all the fields in a single class. JPA provides @Embeddable to do just that.
Here's an example showing how we create a user entity with a has-a credential. The database has all the fields present in a single table:

We have covered three major types of classes that you would typically create when working with JPA:
- Entity: This is the basic unit of bean which is used for persistence
- MappedSuperclass: Class without its own table, but used for common field inheritance by entities
- Embeddable: Class without its own table, properties of which can be persisted via embedding it in another entity
- Embedded Linux Projects Using Yocto Project Cookbook
- Getting Started with React
- AIRAndroid應用開發實戰
- C/C++常用算法手冊(第3版)
- Functional Programming in JavaScript
- C語言程序設計案例式教程
- 你必須知道的204個Visual C++開發問題
- 網絡爬蟲原理與實踐:基于C#語言
- 大數據分析與應用實戰:統計機器學習之數據導向編程
- 零基礎Java學習筆記
- 軟件測試教程
- Unity&VR游戲美術設計實戰
- Java程序設計教程
- Mobile Forensics:Advanced Investigative Strategies
- ROS機器人編程實戰