Mapping Entity Relationships in EJB3

This section explains how to map entity relationships under EJB 3.0. The annotations used are included in package javax.persistence.

Naming Convention: The relationship annotations first refer to the current entity. Mother-Child would be @OneToMany from the Mother entity and @ManyToOne from the Child entity.


@OneToOne


@OneToOne(targetEntity=com.oxbsystems.ejb.entity.service.workflow.Status.class)
public Status getCompletionStatus() {
...

If the OneToOne relationship is bidirectional, the other side of the relationship should include the mappedBy annotation property, such as:


@OneToOne(targetEntity = com.oxbsystems.ejb.entity.shipment.air.Consolidation.class, mappedBy="manifest")
public Consolidation getConsolidation() {
...


@ManyToOne


@ManyToOne(targetEntity=com.oxbsystems.ejb.entity.service.workflow.Status.class)
public Status getStatus() {
...


@OneToMany Unidirectional
The @JoinColumn must be used to indicate the column name of the foreign key in the table that corresponds to the other side of the relationship.


@OneToMany(targetEntity=com.oxbsystems.ejb.entity.service.workflow.TaskTemplate.class, cascade = { CascadeType.ALL })
@JoinColumn(name = "workflowTemplate_id")
public SortedSet getTaskTemplateSet() {
...

If the relationship is managed through a Map, mapping should be done as follows:

@OneToMany(fetch = FetchType.EAGER, cascade = { CascadeType.ALL }, mappedBy = "word")
@MapKey(name = "language")
private Map<String, LocalWord> localMap;

In this case “word” is a property in the opposite entity and a foreign key in the corresponding table. The map key corresponds to a language code, which is also a property in the opposite entity. So mapping a Map in this way requires that the key value be a property of the value class. In this case, the class LocalWord has a “language” property. This language property is used as a Key when adding a LocalWord to the map.


@OneToMany Bidirectional
This takes advantage of an existing @ManyToOne relationship:


@OneToMany(targetEntity=com.oxbsystems.ejb.entity.service.workflow.Task.class, mappedBy="workflow")
public SortedSet getTaskSet() {
...

In this case, the opposite entity (Task) has a @ManyToOne annotation to map workflow…thus, mappedBy=”workflow” above:


@ManyToOne(targetEntity=com.oxbsystems.ejb.entity.service.workflow.Workflow.class)
public Workflow getWorkflow() {
...


@ManyToMany Unidirectional


@ManyToMany(targetEntity = com.oxbsystems.ejb.entity.service.air.route.Airport.class)
@JoinTable(name="city_airport", joinColumns={@JoinColumn(name="cityCode")},
inverseJoinColumns={@JoinColumn(name="airportCode")})
public Set getAirportSet() {
...


@ManyToMany Bidirectional
One side needs to be setup as a ManyToMany Unidirectional. The oposite side will use a mappedBy attribute as follows:


@ManyToMany(mappedBy="airportSet")
public Set getCitySet() {
...


Enumerations
By default enumerations will be stored as integers. The following will cause the enumeration to be stored as a String:


@Enumerated(EnumType.STRING)
public Context getContext() {
...


Non-Entity Objects
Sometimes your entities encapsulate objects that are not entity EJBs, such as a binary object containing an image or a collection of Strings. This type or relationship is annotated with the @Basic and @Lob annotations as follows:


@Basic(fetch = FetchType.EAGER)
@Lob
@Column(name = "Roles") //optional
public Set getRoleSet() {
...
}


You must be logged in to post a comment.