Aggregate Mapping, Composer
Many small objects make sense in an OO system that don’t make sense as tables in a database. An Embedded Value maps the values of an object to fields in the record of the object’s owner.
Real-world example
Examples include currency-aware money objects and date ranges. Although the default thinking is to save an object as a table, no sane person would want a table of money values. Another example would be the online orders which have a shipping address like street, city, state. We map these values of Shipping address object to fields in record of Order object.
In plain words
Embedded value pattern let’s you map an object into several fields of another object’s table.
Programmatic Example
Consider online order’s example where we have details of item ordered and shipping address. We have Shipping address embedded in Order object. But in database we map shipping address values in Order record instead of creating a separate table for Shipping address and using foreign key to reference the order object.
First, we have POJOs Order
and ShippingAddress
1public class Order {
2
3 private int id;
4 private String item;
5 private String orderedBy;
6 private ShippingAddress ShippingAddress;
7
8 public Order(String item, String orderedBy, ShippingAddress ShippingAddress) {
9 this.item = item;
10 this.orderedBy = orderedBy;
11 this.ShippingAddress = ShippingAddress;
12 }
1public class ShippingAddress {
2
3 private String city;
4 private String state;
5 private String pincode;
6
7 public ShippingAddress(String city, String state, String pincode) {
8 this.city = city;
9 this.state = state;
10 this.pincode = pincode;
11 }
12}
Now, we have to create only one table for Order along with fields for shipping address attributes.
1CREATE TABLE Orders (Id INT AUTO_INCREMENT, item VARCHAR(50) NOT NULL, orderedBy VARCHAR(50) city VARCHAR(50), state VARCHAR(50), pincode CHAR(6) NOT NULL, PRIMARY KEY(Id))
While performing the database queries and inserts, we box and unbox shipping address details.
1final String INSERT_ORDER = "INSERT INTO Orders (item, orderedBy, city, state, pincode) VALUES (?, ?, ?, ?, ?)";
2
3public boolean insertOrder(Order order) throws Exception {
4 var insertOrder = new PreparedStatement(INSERT_ORDER);
5 var address = order.getShippingAddress();
6 conn.setAutoCommit(false);
7 insertIntoOrders.setString(1, order.getItem());
8 insertIntoOrders.setString(2, order.getOrderedBy());
9 insertIntoOrders.setString(3, address.getCity());
10 insertIntoOrders.setString(4, address.getState());
11 insertIntoOrders.setString(5, address.getPincode());
12
13 var affectedRows = insertIntoOrders.executeUpdate();
14 if(affectedRows == 1){
15 Logger.info("Inserted successfully");
16 }else{
17 Logger.info("Couldn't insert " + order);
18 }
19}
Use the Embedded value pattern when