tags:

views:

47

answers:

2

How to make Unidirectional Relationship in EJB 3.0 Entity-Beans (JPA)?

For example Customer know about Order but Order has not any method for Customer. using (@OneToMany or @OneToOne or @ManyToMany)

Regards

+1  A: 

Here's how you'd make a unidirectional @OneToMany relationship using JPA 2.0:

@Entity
public class Customer {
  @Id
  @Column(name="cust_id")
  private long id;
  ...
  @OneToMany
  @JoinColumn(name="owner_id", referencedColumnName="cust_id")
  private List<Order> order;
  ...
}

@Entity
public class Order {
    @Id
    @Column(name="order_id")
    private long id;
    ...
}

Relational database:

Customer:

+---------+---------+------+-----+---------+-------+
| Field   | Type    | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| cust_id | int(11) | NO   | PRI | NULL    |       |
+---------+---------+------+-----+---------+-------+

Order:

+----------+---------+------+-----+---------+-------+
| Field    | Type    | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| order_id | int(11) | NO   | PRI | NULL    |       |
| owner_id | int(11) | NO   | MUL | NULL    |       |
+----------+---------+------+-----+---------+-------+
reverendgreen
Note that JPA 1.0 does **not** support unidirectional `OneToMany` relationship **without** a `JoinTable`. In other words, you cannot map the above tables model with a unidirectional `OneToMany` and it does thus not illustrate your answer accurately.
Pascal Thivent
Pascal is correct. The above example works only for JPA 2.0.
reverendgreen
A: 

Leaving "uni-directional" aside for the moment, one could model a Customer-Order relationship as follows.

@Entity
public class Customer {
  // ...
  @Id @GeneratedValue
  int id;
  @OneToMany(cascade = CascadeType.ALL, mappedBy = "customer")
  Set<Order> orders;
  // ...
}

@Entity
public class Order {
  // ...
  @ManyToOne(optional = false)
  Customer customer;
  // ...
}

Here I'm assuming that each Order has exactly one Customer. In the database, the Order table would have a "customer_id" column with a foreign key to the Customer table's "id" column. The DDL would look something like the following.

CREATE TABLE Customer (
  id INT NOT NULL,
  ...
  PRIMARY KEY (id)
);

CREATE TABLE Order (
  ...
  customer_id INT NOT NULL,
  ...
  FOREIGN KEY (customer_id) REFERENCES Customer (id)
);

Although the Customer class contains a collection of orders, this doesn't actually affect the database structure in any way; it's just a convenient way of retrieving/managing orders that belong to the customer. For example, you can drop the "orders" member from Customer altogether and rely on queries to fetch these records instead.

The point I'm trying to make is that, from the perspective of the database, there really is no such thing as a "uni-directional" relationship. The example reverendgreen provided will produce Java classes where there is no direct way to get a Customer object from an Order object, but the resulting database structure will be identical (ignoring minor differences in column names). You can always find the customer for a given order by means of a query.

C P1R8
As I wrote in my comment, the resulting database structure **won't** be identical with JPA 1.0, JPA 1.0 needs a `JoinTable` to represent a unidirectional `OneToMany`.
Pascal Thivent
After reading your answer, I updated some entities in a project I'm working on to use the mark-up you mentioned in your example. It functions just fine -- the database structure is the same, and the child classes contain no direct reference to the parent class. I did not need a @JoinTable annotation. Dependencies as follows: hibernate-annotations 3.4.0.GA, hibernate-commons-annotations 3.1.0.GA, hibernate-core 3.3.2.GA, hibernate-entitymanager 3.4.0.GA, persistence-api 1.0. Is this just a case of Hibernate going beyond the JPA 1.0 spec?
C P1R8
Yes, exactly, this is Hibernate specific, `JoinColumn` is not allowed on `OneToOne` in **standard** JPA 1.0. I provided relevant references in [@OneToMany without inverse relationship and without a join table?](http://stackoverflow.com/questions/2095998/onetomany-without-inverse-relationship-and-without-a-join-table/3517474#3517474)
Pascal Thivent