Definition
Three levels of object relationships from weakest to strongest.
- Association (uses-a): object A uses object B. Both independent, no ownership. UML: plain arrow (-->).
- Aggregation (has-a weak): A has B. B can exist without A. B survives A's destruction. UML: hollow diamond.
- Composition (has-a strong): A owns B. B's lifecycle is tied to A. B destroyed with A. UML: filled diamond.
- UML diamond is on the parent side (the whole). Hollow = weak ownership. Filled = strong ownership.
At National Bank of India: association means TradeService uses MarketDataProvider (two colleagues who work together but neither owns the other). Aggregation means TradingDepartment has Traders (team roster: if department dissolves, traders move elsewhere). Composition means Account owns Transactions (pages in a passbook: destroy the passbook, the pages are gone).
Understanding the Concepts
What is association vs aggregation vs composition?
Three levels of coupling from weakest to strongest. Association is a uses-a relationship with no ownership. Aggregation is a has-a relationship where the part survives the whole. Composition is an owns-a relationship where the part's lifecycle is tied to the whole.
What does each relationship look like in code?
package com.bank.relationships;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
// Association: TradeService uses MarketDataProvider
public class TradeService {
private final MarketDataProvider marketData; // uses
public TradeService(MarketDataProvider marketData) {
this.marketData = marketData;
}
public BigDecimal getQuote(String symbol) {
return marketData.fetchPrice(symbol);
}
}
// Neither owns the other. Both independent. Injected via Spring.
// Aggregation: Portfolio has Stocks
public class Portfolio {
private final List<Stock> stocks = new ArrayList<>();
public void addStock(Stock stock) { stocks.add(stock); } // created outside
public List<Stock> liquidate() {
var released = new ArrayList<>(stocks);
stocks.clear();
return released; // stocks survive, can be added to another portfolio
}
}
// Composition: TradeOrder owns OrderLines
public class TradeOrder {
private final String orderId;
private final List<OrderLine> lines = new ArrayList<>();
public TradeOrder(String orderId) { this.orderId = orderId; }
public void addLine(String symbol, int qty, BigDecimal price) {
lines.add(new OrderLine(orderId + "-L" + (lines.size() + 1), symbol, qty, price));
// Order creates order lines internally
}
public void cancel() { lines.clear(); } // lines destroyed with order
}
What is the UML notation?
Association: TradeService ────────→ MarketDataProvider
(plain line with arrow: uses)
Aggregation: Portfolio ◇─────────→ Stock
(hollow diamond: has, part survives)
Composition: TradeOrder ◆─────────→ OrderLine
(filled diamond: owns, part dies with whole)
Diamond is on the PARENT side (the whole).
How do all three compare?
| Aspect | Association | Aggregation | Composition |
|--------|------------|-------------|-------------|
| Relationship | Uses-A | Has-A (weak) | Owns-A (strong) |
| Lifecycle | Independent | Independent | Bound |
| Child survives? | Yes | Yes | No |
| UML | Arrow | Hollow diamond | Filled diamond |
| JPA cascade | None | None | cascade ALL |
| Example | Service uses Provider | Portfolio has Stocks | Order owns Lines |
How does JPA map these relationships?
Association uses a plain @ManyToOne or @OneToMany with no cascade. Aggregation uses @OneToMany with cascade on persist only, because children survive the parent. Composition uses @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) because children die when removed from the parent.
// Composition in JPA: Account owns Transactions
@Entity
public class Account {
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<Transaction> transactions = new ArrayList<>();
// Deleting an Account deletes all its Transactions
}
// Aggregation in JPA: Portfolio has Stocks
@Entity
public class Portfolio {
@OneToMany(cascade = CascadeType.PERSIST)
private List<Stock> stocks = new ArrayList<>();
// Deleting a Portfolio does NOT delete Stocks
}
What is the decision rule?
Can the part exist meaningfully without the whole? Yes and no ownership means association. Yes but contained means aggregation. No means composition. In banking terms: a TradeService and a MarketDataProvider are independent colleagues (association). A Portfolio contains Stocks, but those Stocks exist independently on the exchange (aggregation). A TradeOrder creates and owns its OrderLines, which have no meaning outside that order (composition).
What are common mistakes?
Using composition when aggregation is appropriate prevents parts from being reused. Using aggregation when composition is needed causes orphaned records in the database.
// WRONG: aggregation when composition is needed
@OneToMany // no cascade, no orphanRemoval
private List<OrderLine> lines; // deleting Order leaves orphan OrderLines in DB!
// CORRECT: composition for owned children
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
private List<OrderLine> lines; // deleting Order removes all OrderLines
What should a senior engineer know?
- In Domain-Driven Design, composition maps to entities within an Aggregate Root. The Aggregate Root controls the lifecycle of its children. External code never holds a direct reference to a child entity.
- In event-driven architecture, associations are cross-service references (service A references service B by ID), aggregation is within-service collections (a service holds a list of related records), and composition is within-aggregate ownership (an aggregate root owns its value objects and child entities).
- In microservices, composition never crosses service boundaries. If two objects are in different services, the relationship is always association by ID reference, never composition.
What are common interview follow-up questions?
- How does garbage collection relate to composition in Java?
- How do you model composition in a relational database?
- Can composition exist without an ORM like JPA?
Visual Overview
RELATIONSHIP STRENGTH ───────────────────────────────────────── Weakest Strongest Association Aggregation Composition (uses-a) (has-a weak) (owns-a strong) A ────→ B A ◇────→ B A ◆────→ B independent B survives A B dies with A BANKING EXAMPLES TradeService ────→ MarketDataProvider (association) Portfolio ◇────→ Stock (aggregation) TradeOrder ◆────→ OrderLine (composition)
Key Takeaway
Three object relationships from weakest to strongest: association (uses: plain arrow in UML, both independent), aggregation (has: hollow diamond, part survives whole), composition (owns: filled diamond, part dies with whole). The decision question: can the part exist meaningfully without the whole? No ownership at all means association. Part survives means aggregation. Part dies means composition.
In UML, the diamond is on the parent side: hollow diamond means I have parts but do not own them (aggregation). Filled diamond means I own parts and they die with me (composition).
Remember one sentence: association means uses (independent), aggregation means has (part survives), composition means owns (part dies with whole), and the UML diamond is hollow for weak ownership and filled for strong ownership.
---