A one-to-many relationship occurs when one entity is related to many occurrences in another entity.
“One-to-many” example
This is a one-to-many relationship table design, a STOCK table has many occurrences STOCK_DAILY_RECORD table.
Hibernate implementation
In Hibernate, “one” means an object, “many” means a Collection interface. This “one-to-many” relationship can implemented in two ways :
- Hibernate XML Mapping file
- Hibernate Annotation
1. Hibernate XML mapping file
In XML mapping way, you need two Java classes to hold the table data,
- Stock.java -> STOCK table
- StockDailyRecord.java -> STOCK_DAILY_RECORD table
and two XML mapping files to describe the table relationship.
- Stock.hbm.xml -> STOCK table
- StockDailyRecord.hbm.xml -> STOCK_DAILY_RECORD table
Stock.java
public class Stock implements java.io.Serializable { ... private Set<StockDailyRecord> stockDailyRecords = new HashSet<StockDailyRecord>(); public Set<StockDailyRecord> getStockDailyRecords() { return this.stockDailyRecords; } ... public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) { this.stockDailyRecords = stockDailyRecords; } }
StockDailyRecord.java
public class StockDailyRecord implements java.io.Serializable { private Stock stock; ... public Stock getStock() { return this.stock; } public void setStock(Stock stock) { this.stock = stock; } ... }
Stock.hbm.xml
<hibernate-mapping> <class name="com.mkyong.common.Stock" table="stock" ...> .... <set name="stockDailyRecords" inverse="true" table="stock_daily_record" ...> <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.mkyong.common.StockDailyRecord" /> </set> </class> </hibernate-mapping>
The inverse=”true” is tells Hibernate about the relationship owner is belong to other side , not the class. More detail….
StockDailyRecord.hbm.xml
<hibernate-mapping> <class name="com.mkyong.common.StockDailyRecord" table="stock_daily_record" ...> <many-to-one name="stock" class="com.mkyong.common.Stock" ...> <column name="STOCK_ID" not-null="true" /> </many-to-one> ... </class> </hibernate-mapping>
2. Hibernate annotation
In annotation way, only two classes are required, all the relationships are declared inside the Java classes.
- Stock.java -> STOCK table
- StockDailyRecord.java -> STOCK_DAILY_RECORD table
Stock.java
... @Entity @Table(name = "stock", catalog = "mkyong", uniqueConstraints = { @UniqueConstraint(columnNames = "STOCK_NAME"), @UniqueConstraint(columnNames = "STOCK_CODE") }) public class Stock implements java.io.Serializable { ... private Set<StockDailyRecord> stockDailyRecords = new HashSet<StockDailyRecord>(0); @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock") public Set<StockDailyRecord> getStockDailyRecords() { return this.stockDailyRecords; } public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) { this.stockDailyRecords = stockDailyRecords; } ...
The “mappedBy” annotation is equal to inverse=”true” in XML mapping file.
StockDailyRecord.java
... @Entity @Table(name = "stock_daily_record", catalog = "mkyong", uniqueConstraints = @UniqueConstraint(columnNames = "DATE")) public class StockDailyRecord implements java.io.Serializable { ... private Stock stock; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "STOCK_ID", nullable = false) public Stock getStock() { return this.stock; } public void setStock(Stock stock) { this.stock = stock; } ...
Test It
Run the example, both annotation and XML mapping file will generate the same output. Hibernate inserts a row into the STOCK table and a row into the STOCK_DAILY_RECORD table.
...
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
Stock stock = new Stock();
stock.setStockCode("4715");
stock.setStockName("GENM");
StockDailyRecord stockDailyRecords = new StockDailyRecord();
stockDailyRecords.setPriceOpen(new Float("1.2"));
stockDailyRecords.setPriceClose(new Float("1.1"));
stockDailyRecords.setPriceChange(new Float("10.0"));
stockDailyRecords.setVolume(2000000L);
stockDailyRecords.setDate(new Date());
stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);
session.save(stockDailyRecords);
session.save(stock);
session.getTransaction().commit();
...Saving the session.save(stockDailyRecords); is not necessary, you can enable the cascade option to save the stockDailyRecords automatically, read more about it…
Output
Hibernate:
insert
into
mkyong.stock
(STOCK_CODE, STOCK_NAME)
values
(?, ?)
10:41:37,492 DEBUG StringType:133 - binding '4715' to parameter: 1
10:41:37,492 DEBUG StringType:133 - binding 'GENM' to parameter: 2
Hibernate:
insert
into
mkyong.stock_daily_record
(STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
values
(?, ?, ?, ?, ?, ?)Download Full Project
In this tutorial, many files and configuration steps are hidden, only the important files are remark. If you are interest to do the hand-on, you can download the full project here.
- Hibernate one-to-many XML mapping example – Full project download.
- Hibernate one-to-many annotation example – Full project download.
These two projects are developed in Eclipse IDE, using Maven as project management tool, and MySQL as database engine. The MySQL table creation scripts are stored in “db” folder.



Nice article !. One question : Is it necessary to have a many-to-one relationship always on the other side of the one-to-many relationship (like the one you mentioned above) or it’s needed only in specific cases (if yes what are they) ?
yes, configure the relationship in both sides are always recommended, else the other site (many-to-one) or stock_daily_record can not retrieve the data from stock table directly, you may need some workaround for it.
If you really sure the other site (many-to-one) should not have the relationship, you can just disable it, the Hibernate will still work. But you have to manage both relationship manually. In most cases, it just doesn’t make sense.
ok great…thanks for the reply
[...] will take this one-to-many example for the mutable demonstration. In this mapping file, a Stock is belong to many StockDailyRecord. [...]
[...] the program failed to execute the cascade operation to the related entities. I will take this one-to-many hibernate example for the [...]