Wednesday, March 14, 2012

JPA2 Feature Saving the order of elements of an association

In JPA 2 there is a new feature for assuring that an association has always the same order of elements.
That means the order of the elements of an association, which is realized by a list, is stored in the database as well.
There is a 1:n - association.
The 1-side has the according collection of entities of the n-side.
This collection can be defined as list in the specific entity class.
If you want, that the list behaves deterministic, that the order must be stored:
therefore you can use the new annotation in JPA 2:

@OrderColumn

@Entity
public class A implements Serializable {
   ...
   @OneToMany
   @OrderColumn
   private List<B> bs = new ArrayList<B>();
   ...
}    

@Entity
public class B implements Serializable {
 ...
 @Id
 @Generated
  private Long id;
  private String orderNumber;
 ...
}

In this case in the entity B a new field with the name BS_ORDER is created, which can not be seen by the entity itself. It is used for saving the order of the associated entities of B to A.
So the order of elements of the collection is always the same, when the entities of A are load for e.g. with mode FetchType.EAGER.
When would you use it?
If the sort order @OrderBy has an bad impact on access execution or the order of subject-specific attributes / columns still produces an undefined order.


Saving of elements per key of an association, which is realized by Map, was possible in the previous JPA Version:
In the example above bs is not created as List, but as Map.
Then the annotation @MapKey can define the key with whom one can access the collection / association.
The Default @MapKey always defines the primary key of the entity for accessing the map.
If you want to use another column as the key, you can use the parameter name:

@MapKey(name="columnName").
The result of the above example is:
   @OneToMany
   @MapKey(name="orderNumber")
   private Map<String, B> bs = new HashMap<String,B>();

For what do we need an key based access of an association?
It makes sense, if you know, that the access of this annotation regarding the business logic
usually is done per using the orderNumber and the primary key is a more technical key, which is used in other subordinated use cases like archiving the data.
So one can express very clean:

String aOrderNumber;
....
B myBEntity = a.getBs().get(aOrderNumber);


No comments:

Post a Comment