Tuesday, March 13, 2012

Treatment of Value Types in JPA Hibernate

How is value types approached in JPA / Hibernate?

First of all the definition of value types.
Value types are no real entities. They have no life cycles, that means they will not be created, later on edited or deleted. They exist since beginning of system life.
True entities, which are marked with @Entity, do have a life cycle and they a corresponding representation in the database.
Now there a certain cases in which one wants to use value types:

  • as constants, which are stored as attribute to a entity in the database
  • values, which are stored next to a certain entity
Constants can be made easily in Java with enums:
public enum EnumXY{
   constantValue1, constantValue2, constantValue3;
}

They are used with every entity:
@Entity
public class MyEntity implements Serializable {
    ...
    @Enumerated
    private EnumXY flag;
    ...
}

In the table per default the position of the value(ordinal number) of the corresponding entity is stored as integer. If the MyEntity flag gets the constantValue3 assigned, than value 2 is stored in the table of MyEntity.
This can be configured with @Enumerated(EnumType.ORDINAL) (default) or @Enumerated(EnumType.STRING). The latter the name of the constant will be stored in the corresponding column of the database table. Here it is constantValue3.

What happens if someone wants to store multiple values of a value type to an entity?
This is also possible in JPA 2:
With the help of @ElementCollection you can express, that the collection is made of values of a value type and not a collection of normal entities.
 @ElementCollection
private List<String> basetypeValues = new ArrayList<String>();
First of all  CollectionsOfElements is the hibernate specific annotation.
In JPA you should use @ElementCollection.
Example:
@Entity
public class X implements Serializable {
  @Id
  @Generated
  private Long id;
  @ElementCollection
   private List<String> remarks = new ArrayList<String>();
    ...
}

@Test
public void testElementCollection() {
  ...
  X x = new X();
  private List<String> remarks = new ArrayList<String>();
  remarks.add("remark1");
  remarks.add("remark2");
  remarks.add("remark3");
  x.setRemarks(remarks);
  em.persist(x);
  ...
}

What happens in the database?
An "ElementCollection" will always be stored in a separate table.
This can be defined more precisely with @CollectionTable. JoinColum(s) is used for the definition of the foreignKey(s):
@CollectionTable(
   name = "nameOfCollectionTable",
   joinColumns = @JoinColum(name="fk")
)

Result:

Table X:
id column1 column2
3 .....         ....

Table Remarks:
id remarks 
3  remark1
3  remark2
3  remark3








No comments:

Post a Comment