Reputation: 42050
Suppose I have to develop a simple data model in Java for Order
, which contains Order Items
. It looks like Order
should hold a reference to a collection Order Items
Now what if Order
and Order Items
are stored in a database? Should the Order
still hold a reference to the collection or just a simple function retrieveItemsByOrderId
should be provided instead?
Upvotes: 1
Views: 7277
Reputation: 4769
I think you should keep a reference to OrderItem collection in your Order model class. Then, you could implement the method getOrderItems() that retrieves the items from the db based on the order id.
This query should be performed only if you need to access the order items (search for LAZY LOADING) and not every time you load the Order entity from DB.
Using a reference to OrderItem collection in your Order model class will leverage your application in case you need to access twice the order items in the same request-response flow.
A skeleton of getOrderItems() method would be like this:
public List<OrderItem> getOrderItems(){
if(this.orderItems==null)
// perform the query
// set the this.orderItems values
}
return this.orderItems
}
Upvotes: 1
Reputation: 76709
Now what if Order and Order Items are stored in a database? Should the Order still hold a reference to the collection or just a simple function retrieveItemsByOrderId should be provided instead?
This would depend on how your object model is used by the persistence layer to map classes to the database tables. If you are using Hibernate/JPA/EclipseLink/Toplink or a similar ORM framework, you would merely have a getter method in your Order
class that would return the collection of OrderItem
instances. Partial code representation would be:
class Order
{
private long id;
private Set<OrderItem> orderItems;
...
public Set<OrderItem> getOrderItems()
{
return orderItems;
}
public void setOrderItems(Set<OrderItem> orderItems)
{
this.orderItems = orderItems;
}
}
class OrderItem
{
private Order order;
...
public Order getOrder()
{
return order;
}
public void setOrder(Order order)
{
this.order = order;
}
}
I haven't listed all annotations in use by the frameworks, including the keys for each entity class, but you'll need to do this to get things working. The salient points however are:
Order
class contains the Id, which may be the natural key (or may be a generated one).getOrderItems
method will result in the Set
of order items associated with an order to be returned. Note that most ORMs will lazily fetch collections, so you'll need to understand a few more concepts like working with managed and detached entities to actually get this to work; you might need to write an application service to do the work of merging detached entities and then fetch the collection.One of the comments stated that there is no need to reference the Order
from the OrderItem
class. This would lead to a unidirectional relationship instead of a bidirectional one. You can use unidirectional relationships in most ORM frameworks, but consider the following:
Order
from OrderItem
without any further effort on your part, while others might require you to use a Join table. If you are persisting an object graph in the database, then it is imperative to know which OrderItem
maps to an Order
; by removing the reference from the OrderItem
, you will be forced to map this information elsewhere, in a different entity and usually resulting in a different table; this is the Join table that are referred to previously.Order
is responsible for accessing OrderItem
instances, then you do not need bidirectional relationships. But if you find yourself needing to access the Order
for an OrderItem
, then you will need a bidirectional relationship. I would suggest reading the Mutual Registration Pattern, so that you will always be able to maintain referential integrity irrespective of any mutation operations performed on Order
or OrderItem
classes in such a case. Without that pattern, you are almost always going to find yourself seeing vague, unexplained and incorrect object graphs resulting in an inconsistent database state.If you are not using ORM or you don't intend to, then it would depend on you are accessing the OrderItem
instances; in short, it depends on how you are writing your persistence layer. If you are using the DAO pattern, then adding a new method retrieveItemsByOrderId
into your DAO interface would be the solution.
Upvotes: 2