Defining the entity layer

The first thing we need to check is the list of entity objects that will map the database tables. The first one is the Customer @Entity class, as follows:

@Entity
@NamedQuery(name = "Customers.findAll",
query = "SELECT c FROM Customer c ORDER BY c.id",
hints = @QueryHint(name = "org.hibernate.cacheable", value =
"true") )
public class Customer {
@Id
@SequenceGenerator(
name = "customerSequence",
sequenceName = "customerId_seq",
allocationSize = 1,
initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"customerSequence")
private Long id;

@Column(length = 40)
private String name;

@Column(length = 40)
private String surname;

@OneToMany(mappedBy = "customer")
@JsonbTransient
public List<Orders> orders;

// Getters / Setters omitted for brevity
}

Let's go through the single annotations we have included in the entity class:

  • The @Entity annotation makes this class eligible for persistence. It can be coupled with the @Table annotation to define the corresponding database table to a map. If it's not included, like in our case, it will map a database table with the same name.
  • The @NamedQuery annotation (placed at the class level) is a statically defined SQL statement featuring a query string. Using named queries in your code improves how your code is organized since it separates the JPA query language from the Java code. It also avoids the bad practice of embedding string literals directly in your SQL, thus enforcing the use of parameters instead.
  • The @Id annotation specifies the primary key of an entity, which will be unique for every record.
  • The @SequenceGenerator annotation is used to delegate the creation of a sequence as a unique identifier for primary keys. You will need to check that your database is capable of handling sequences. On the other hand, although this isn't the default option, this is considered a safer alternative since the identifier can be generated prior to executing the INSERT statement.
  • The @Column annotation is used to tell Hibernate ORM that the Java field maps a database column. Note that we have also specified a constraint in terms of the size of the column. Since we will let Hibernate ORM create our database structures from Java code, all the constraints that are declared in the Java class will effectively turn into database constraints.
  • Finally, we had to apply two annotations on top of the orders field:
    • The @OneToMany annotation defines a one-to-many relationship with the Orders table (that is, one customer is associated with many orders).
    • The @JsonbTransient annotation prevents mapping the field to the JSON representation (since the reverse mapping for this relationship is included in the Orders class, mapping this field to JSON would cause a StackOverflow error).
In our code example, we have omitted the getter/setter methods for the sake of brevity. These are, however, needed by Hibernate ORM to perform entity reads and writes against the database. In the Making data persistence easier with Hibernate Panache section later in this chapter, we will learn how to make our code leaner and cleaner by extending the PanacheEntity API.

The Customer entity, in turn, references the following Orders class, which provides the other side of the one-to-many annotation:

@Entity
@NamedQuery(name = "Orders.findAll",
query = "SELECT o FROM Orders o WHERE o.customer.id = :customerId ORDER BY o.item")
public class Orders {
@Id
@SequenceGenerator(
name = "orderSequence",
sequenceName = "orderId_seq",
allocationSize = 1,
initialValue = 1)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"orderSequence")
public Long id;

@Column(length = 40)
public String item;

@Column
public Long price;

@ManyToOne
@JoinColumn(name = "customer_id")
@JsonbTransient
public Customer customer;

// Getters / Setters omitted for brevity
}

It's worth noting that the named query for this class is slightly more elaborated since Orders.findAll NamedQuery uses a parameter in order to filter the orders by a specific customer.

Since the Customer structure and the Orders structure make up a bidirectional association, we need to map the corresponding Customer field to the @javax.persistence.ManyToOne annotation.

We also have included the @javax.persistence.JoinColumn annotation to indicate that this entity is the owner of the relationship. In database terms, this means that the corresponding table has a column with a foreign key for the referenced table. Now that we have a class where data will be stored, let's inspect the Repository class, which is used to access data from the RDBMS.

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

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