Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To initialize or not initialize JPA relationship mappings?

Tags:

In one to many JPA associations is it considered a best practice to initialize relationships to empty collections? For example.

@Entity public class Order {      @Id    private Integer id;     // should the line items be initialized with an empty array list or not?    @OneToMany(mappedBy="order")    List<LineItem> lineItems = new ArrayList<>();  } 

In the above example is it better to define lineItems with a default value of an empty ArrayList or not? What are the pros and cons?

like image 472
ams Avatar asked Dec 21 '13 03:12

ams


People also ask

How do you initialize a lazy load?

Implementing a Lazy-Initialized Property To implement a public property by using lazy initialization, define the backing field of the property as a Lazy<T>, and return the Value property from the get accessor of the property. The Value property is read-only; therefore, the property that exposes it has no set accessor.

What is the use of Hibernate initialize?

next difference is that Hibernate. initialize generates and executes additional sql for fetching data. So you can use it after session is closed. When you use Eager fetch in entity it's always fetch that collections during finding data (under the connection session ) in database, but not after it.

How do I map a OneToOne JPA?

The best way to map a @OneToOne relationship is to use @MapsId . This way, you don't even need a bidirectional association since you can always fetch the PostDetails entity by using the Post entity identifier. This way, the id property serves as both Primary Key and Foreign Key.

How do you create a one to many relationship in JPA?

Many-To-One relation between entities: Where one entity (column or set of columns) is/are referenced with another entity (column or set of columns) which contain unique values. In relational databases these relations are applicable by using foreign key/primary key between tables.


2 Answers

JPA itself doesn't care whether the collection is initialized or not. When retrieving an Order from the database with JPA, JPA will always return an Order with a non-null list of OrderLines.

Why: because an Order can have 0, 1 or N lines, and that is best modeled with an empty, one-sized or N-sized collection. If the collection was null, you would have to check for that everywhere in the code. For example, this simple loop would cause a NullPointerException if the list was null:

for (OrderLine line : order.getLines()) {     ... } 

So it's best to make that an invariant by always having a non-null collection, even for newly created instances of the entity. That makes the production code creating new orders safer and cleaner. That also makes your unit tests, using Order instances not coming from the database, safer and cleaner.

like image 55
JB Nizet Avatar answered Sep 29 '22 17:09

JB Nizet


I would also recommend using Guava's immutable collections, e.g.,

import com.google.common.collect.ImmutableList; // ... @OneToMany(mappedBy="order") List<LineItem> lineItems = ImmutableList.of(); 

This idiom never creates a new empty list, but reuses a single instance representing an empty list (the type does not matter). This is a very common practice of functional programming languages (Scala does this too) and reduces to zero the overhead of having empty objects instead of null values, making any efficiency argument against the idiom moot.

like image 44
Giovanni Botta Avatar answered Sep 29 '22 17:09

Giovanni Botta