Java Persistence API (JPA) Part 2: Building Relationships ☕

|

Mapping Relationships 🗾

Name Target Purpose
JoinColumn F, M Used to specify an entity relationship. This is used in many-to-one and one-to-many associations.
ManyToMany F, M Define a many-to-many relationship between the join Tables.
ManyToOne F, M Define a many-to-one relationship between the join Tables.
MapKey F, M Allows a key to be specified when making an association with a Map object.
OneToMany F, M Define a one-to-many relationship between the join Tables.
OneToOne F, M Define a one-to-one relationship between the join Tables.
OrderBy F, M Allows the ordering of a collection to be defined as
it is retrieved.    

One end of the relationship must be marked as the owner. You must manage both ends of the relationship.

One to one

One to many

Many to many

The callbacks

Callback methods can perform actions at different stages of persistence operations.

Imagine that you want to update a customer record, but, before you update, you want to remove the hyphen from the zip code if one is present. JPA provides listeners for these kinds of activities before and after each fetch, insert, or update operation.

The callback methods can be annotated as any of the following:

  • @PostLoad
  • @PrePersist
  • @PostPersist
  • @PreUpdate
  • @PostUpdate
  • @PreRemove
  • @PostRemove

Embedded objects

As you’ve seen so far, the Customer entity has the address information inline in the entity itself. What if you want to apply class normalization concepts and come up with a separate Address class and refer to that in the Customer entity? After all, an address object could be used with Customer, Employee, Order, or User entities.

All you need is an embedded object. You move the address information into a separate class and mark that class as being embeddable, as shown in Listing 10. Refer to this newly created class from the Customer entity with @Embedded annotations.

@Embeddable
public class Address implements Serializable{
    private String street;

    @Column(name = "APPT",nullable = false)  
    private String appt;

    private String city;
}

Embedded classes are mapped together with their owning entity as part of the state of that entity. However, they cannot be queried separately. Listing 11 illustrates a sample entity that uses an embedded object.

A sample entity using an embedded object.

@Entity
public class Customer {
    @Column(name = "FIRST_NAME", nullable = false,length = 50)
    private String firstName;

    @Embedded
    private Address address;
}

You can write the callback methods in the entity class itself, or you can write them in a separate class and reference them in the entity class with @EntityListeners, as shown in Listing 9.

Inheritance 👪

An entity can extend the following:

Another entity – either concrete or abstract. Another non-entity, supplying behavior or non-persistence state. The attributes you inherit from a non-entity are not persisted. Mapped superclasses, supplying common entity state. Tables in a database have similar fields, but tables are not related to each other. Let’s have a look into the various types of inheritance JPA offers. For this scenario, assume that there are two types of customer: a normal customer who buys products from a physical store and an online customer who buys products over the Internet.

Using Spring What’s the value input from Spring in supporting JPA, you might ask?

The Spring framework supports the JPA API in couple of ways, very similar to support for Hibernate. One way is by providing the classic template: a JpaTemplate class. This class is basically a wrapper around the EntityManager similar to other templates such as HibernateTemplate . The second way is by allowing the developer to use plain JPA API in the applications via an injected EntityManager class. If you are confused as to what approach to take, go with using plain API if possible. This way, Spring will be used solely for dependency injection thus avoiding any dependencies on its framework classes.

Should you have earlier versions (before 3.x), perhaps sticking to template style might be easier. Let’s explore both of these use cases in detail.

Basically, Spring encapsulates the EntityManagerFactory in its own FactoryBean imple- mentation and injects them into the applications where it is needed. Spring uses two implementations of FactoryBean for providing the EntityManager s in respective environments: org.springframework.orm.jpa.LocalEntityManagerFactoryBean This FactoryBean creates the EntityManagerFactory for standalone environments. This implementation provides a simple factory that has limitations. It cannot par- ticipate in global transaction s, cannot work with DataSources . org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean This factory bean provides the EntityManagerFactory for enterprise environments. Note how its classname has the word “Container” embedded in it, compared to the previous LocalEntityManagerFactoryBean class.

« Java Persistence API (JPA) Part 1: Getting Started

Additional Reading

Related Posts