Main Tutorials

Hibernate – One-to-Many example (Annotation)

In this tutorial, it will reuse the entire infrastructure of the previous “Hibernate one to many relationship example – XML mapping” tutorial, enhance it to support Hibernate / JPA annotation.

Project Structure

Review the new project structure of this tutorial.

one to many annotation folder
Note
Since Hibernate 3.6, annotation codes are merged into the Hibernate core module, so, the previous pom.xml file can be reuse.

1. “One-to-many” table relationship

See the previous one to many table relationship again.

one to many table relationship

2. Hibernate Model Class

Update previous model classes – Stock.java and StockDailyRecord.java, and define the annotation code inside.

File : Stock.java


package com.mkyong.stock;

import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "stock", catalog = "mkyongdb", uniqueConstraints = {
		@UniqueConstraint(columnNames = "STOCK_NAME"),
		@UniqueConstraint(columnNames = "STOCK_CODE") })
public class Stock implements java.io.Serializable {

	private Integer stockId;
	private String stockCode;
	private String stockName;
	private Set<StockDailyRecord> stockDailyRecords = new HashSet<StockDailyRecord>(
			0);

	public Stock() {
	}

	public Stock(String stockCode, String stockName) {
		this.stockCode = stockCode;
		this.stockName = stockName;
	}

	public Stock(String stockCode, String stockName,
			Set<StockDailyRecord> stockDailyRecords) {
		this.stockCode = stockCode;
		this.stockName = stockName;
		this.stockDailyRecords = stockDailyRecords;
	}

	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "STOCK_ID", unique = true, nullable = false)
	public Integer getStockId() {
		return this.stockId;
	}

	public void setStockId(Integer stockId) {
		this.stockId = stockId;
	}

	@Column(name = "STOCK_CODE", unique = true, nullable = false, length = 10)
	public String getStockCode() {
		return this.stockCode;
	}

	public void setStockCode(String stockCode) {
		this.stockCode = stockCode;
	}

	@Column(name = "STOCK_NAME", unique = true, nullable = false, length = 20)
	public String getStockName() {
		return this.stockName;
	}

	public void setStockName(String stockName) {
		this.stockName = stockName;
	}

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "stock")
	public Set<StockDailyRecord> getStockDailyRecords() {
		return this.stockDailyRecords;
	}

	public void setStockDailyRecords(Set<StockDailyRecord> stockDailyRecords) {
		this.stockDailyRecords = stockDailyRecords;
	}

}

File : StockDailyRecord.java


package com.mkyong.stock;

import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;

@Entity
@Table(name = "stock_daily_record", catalog = "mkyongdb", 
uniqueConstraints = @UniqueConstraint(columnNames = "DATE"))
public class StockDailyRecord implements java.io.Serializable {

	private Integer recordId;
	private Stock stock;
	private Float priceOpen;
	private Float priceClose;
	private Float priceChange;
	private Long volume;
	private Date date;

	public StockDailyRecord() {
	}

	public StockDailyRecord(Stock stock, Date date) {
		this.stock = stock;
		this.date = date;
	}

	public StockDailyRecord(Stock stock, Float priceOpen, Float priceClose,
			Float priceChange, Long volume, Date date) {
		this.stock = stock;
		this.priceOpen = priceOpen;
		this.priceClose = priceClose;
		this.priceChange = priceChange;
		this.volume = volume;
		this.date = date;
	}

	@Id
	@GeneratedValue(strategy = IDENTITY)
	@Column(name = "RECORD_ID", unique = true, nullable = false)
	public Integer getRecordId() {
		return this.recordId;
	}

	public void setRecordId(Integer recordId) {
		this.recordId = recordId;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "STOCK_ID", nullable = false)
	public Stock getStock() {
		return this.stock;
	}

	public void setStock(Stock stock) {
		this.stock = stock;
	}

	@Column(name = "PRICE_OPEN", precision = 6)
	public Float getPriceOpen() {
		return this.priceOpen;
	}

	public void setPriceOpen(Float priceOpen) {
		this.priceOpen = priceOpen;
	}

	@Column(name = "PRICE_CLOSE", precision = 6)
	public Float getPriceClose() {
		return this.priceClose;
	}

	public void setPriceClose(Float priceClose) {
		this.priceClose = priceClose;
	}

	@Column(name = "PRICE_CHANGE", precision = 6)
	public Float getPriceChange() {
		return this.priceChange;
	}

	public void setPriceChange(Float priceChange) {
		this.priceChange = priceChange;
	}

	@Column(name = "VOLUME")
	public Long getVolume() {
		return this.volume;
	}

	public void setVolume(Long volume) {
		this.volume = volume;
	}

	@Temporal(TemporalType.DATE)
	@Column(name = "DATE", unique = true, nullable = false, length = 10)
	public Date getDate() {
		return this.date;
	}

	public void setDate(Date date) {
		this.date = date;
	}

}

3. Hibernate Configuration File

Puts annotated classes Stock.java and StockDailyRecord.java in hibernate.cfg.xml like this :

File : hibernate.cfg.xml


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mkyongdb</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">password</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="show_sql">true</property>
    <mapping class="com.mkyong.stock.Stock" />
    <mapping class="com.mkyong.stock.StockDailyRecord" />
</session-factory>
</hibernate-configuration>

4. Run It

Run it, Hibernate will insert a row into the STOCK table and a row into the STOCK_DAILY_RECORD table.

File : App.java


package com.mkyong;

import java.util.Date;

import org.hibernate.Session;

import com.mkyong.stock.Stock;
import com.mkyong.stock.StockDailyRecord;
import com.mkyong.util.HibernateUtil;

public class App {
	public static void main(String[] args) {
		
        System.out.println("Hibernate one to many (Annotation)");
	Session session = HibernateUtil.getSessionFactory().openSession();

	session.beginTransaction();

	Stock stock = new Stock();
        stock.setStockCode("7052");
        stock.setStockName("PADINI");
        session.save(stock);
        
        StockDailyRecord stockDailyRecords = new StockDailyRecord();
        stockDailyRecords.setPriceOpen(new Float("1.2"));
        stockDailyRecords.setPriceClose(new Float("1.1"));
        stockDailyRecords.setPriceChange(new Float("10.0"));
        stockDailyRecords.setVolume(3000000L);
        stockDailyRecords.setDate(new Date());
        
        stockDailyRecords.setStock(stock);        
        stock.getStockDailyRecords().add(stockDailyRecords);

        session.save(stockDailyRecords);

	session.getTransaction().commit();
	System.out.println("Done");
	}
}

Output


Hibernate one to many (Annotation)
Hibernate: 
    insert 
    into
        mkyongdb.stock
        (STOCK_CODE, STOCK_NAME) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        mkyongdb.stock_daily_record
        (DATE, PRICE_CHANGE, PRICE_CLOSE, PRICE_OPEN, STOCK_ID, VOLUME) 
    values
        (?, ?, ?, ?, ?, ?)
Done
Download it – Hibernate-one-to-many-annotation.zip (9KB)

Reference

  1. Hibernate Documentation – one to many relationship

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
50 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Salman Khan
6 years ago

how we can do the reference key and reference value column for one to many relationship in spring and hibernate with status column as well as we make a child table for the parent table. plz help me out, I am trying but all the records of phone and email are coming in single row…
Thanks in advance

Tony
6 years ago

Thanks for this 🙂

Shreevardhan
7 years ago

Here I have a confusion. In App.java you have saved stock table once, the you have added to stockDailyRecords object for mapping and connecting both of them. But why is stockDailyRecords object is being added to stock object before saving
again as below???

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stockDailyRecords);

shravanReddy
4 years ago
Reply to  Shreevardhan

actually that is for manyToOne relationship

Ala eddine
6 years ago
Reply to  Shreevardhan

It is one to many bidirectionelle ,we can get which stock these details are stored .

Thieu Anh
7 years ago

-Why i can’t code like that :
@Id
@Column(name = “id”)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
Server show error but if i code :
@Id
@Column(name = “id”)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int getId();
Server run !
– i had tried
“@Id
@Column(name = “id”)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;”
with Hirbernate only one table . It ran . But why not with two table with relation.

Salah
5 years ago
Reply to  Thieu Anh

you can write like this:
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = “STOCK_ID”, unique = true, nullable = false)
private Integer stockId;

@Column(name = “STOCK_CODE”, unique = true, nullable = false, length = 10)
private String stockCode;

@Column(name = “STOCK_NAME”, unique = true, nullable = false, length = 20)
private String stockName;

@OneToMany(fetch = FetchType.LAZY, mappedBy = “stock”)
private Set stockDailyRecords = new HashSet(0);

Derick Daniel
7 years ago

nice tutorial but explanation for the annotations/coding would be more helpful..!

sebastin
8 years ago

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = “STOCK_ID”, nullable = false)
public Stock getStock() {
return this.stock;
}
i dont understand this line any one can explain me

Agustin
8 years ago

I dont know where put hibernate.cfg.xml. I have my persistence.xml with my “Entitys”

Akshay
9 years ago

The thing is if I retireve the child variable it will come with parent details as well, what I want is just that the parent class should get me the child class details only and not other way round

Raed
9 years ago

Hi thanks for the nice Blog but what happen if we try to delete a stock-Object from the DB i think we get an orphan rows from type stock_daily_record ?

thanks

Seetesh Hindlekar
9 years ago

This doesnt look like a One to Many example but just a simple one to one data being inserted into the tables. You need to change the client code to add many records into the Stock table containing many stockdailyrecords.

Ashkan
9 years ago

very useful, Thank you.

Gourav
10 years ago

i have download your code on this url https://mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/ and import in myeclipse id and run i got this error “The archive: C:/Users/abc/.m2/repository/antlr/antlr/2.7.7/antlr-2.7.7.jar which is referenced by the classpath, does not exist.” I’m begginer on java hybernate

Prateek Ashtikar
9 years ago
Reply to  Gourav

It seems that your workstation’s local repository (.m2) don’t have a “antlr-2.7.7.jar” file. Try to add this jar in your class-path or if you’ve maven project, add dependency for the same.

Chirag Chavda
10 years ago

i was working on my own example for one to many relationship in hibernate annotation but i was having some errors so i thought there must be something wrong with my code but when run your source code it keep showing me same error can help me please!!! ?

Marcel Kobain
10 years ago

Thanks for this nice article,

A question :

Is it mandatory to write (an why)

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

>> It is not redundant ?
Why not just add to the stock a list of stockDailyRecords ?

giuseppe
10 years ago

Hi
first of all thanks for all your posts and time. I’m a frequent reader but it’s my first time.
my question is a kind of “best practise” question.

I had to write equals and hash method
ie

@Override
public int hashCode() {
return 13 * id.hashCode();
}

so when the code down is executed

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

I receive a null pointer error, because stockDailyRecords is not saved yet and id is null
you surely know hash method is used for adding items in set

but if I save stockDailyRecords before linking it to stock
I receive an other error because sql says stockid cannot be null.

what is your opinion?
what is best way to avoid this?

thank

Yamir
10 years ago

Hello Mkyong,

I trying to use your example but using spring jpa, but I notice that the children is not persisted on the database.

Marcin
11 years ago

Hi,
Your posts are really helpful and good commented.Thanks a lot.

Best Regards
Marcin

Luis
11 years ago

Nice post, thanks!

One comment be careful if you want to create this schema using

<property name="hibernate.hbm2ddl.auto">update</property>

… you will probably get:

ORA-02261: such unique or primary key already exists in the table

Solution: do not add constraints to your ids, just annotate them like this:

	@Id
	@Column(name = "ID")
	public int getId() {
		return id;
	}

Hope it helps,

Luis

Adeeb
11 years ago

Hi
Can any one tell me, how will be the mapping if STOCK_ID is changed to STK_ID in stock_daily_record table?
Because i am not sure about the columns used while creating mapping in above code since it is not mentioned in description.
Also with this changes, there will be no logical constraint using FOREIGN key relationship between above two tables.

Thanks

Adrien
11 years ago

Thanks for the example.

You probably want to precise in the title/description that your example is WITHOUT a join table.

You also probably want to precise if you’re doing a Unidirectional mapping or a Bidirectional mapping.

Any chance to provide a similar example but with a join table ?

Adrien
11 years ago
Reply to  Adrien
Deepa
11 years ago

Hi, am new to annotations and need to some clarifications on one-to-many relationship which you explained in _https://mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/. Consider stock_id and some set_id will be the primary key for “StockDailyRecord” table. In that case how the mappings will be??

Kindly help me the same.

-Deepa

Joydeep
11 years ago

Hi,
In my case of 1-M mapping, whenever i’m adding the association mapping between two pojo in hibernate config file,the following exception is coming..

“Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTuplizer]”

problem goes after removing the mappings informations from config and hbm files.

1. javaassist.jar is already there.
2. all the required setter/getter is present in POJO classes.

can anybody pls suggest me some way.

john
11 years ago

hi Mkyong.
In app.java file where is this

add()

method declare.

stockDailyRecords.setStock(stock);        
        stock.getStockDailyRecords().add(stockDailyRecords);

And i also want to ask can

session.save(stockDailyRecords);

will run query for insertion of both stock and stockDailyRecords?

Risav Karna
11 years ago

You don’t need setter methods for id fields as they are generated for you by Hibernate itself. Providing a set method to the client classes may cause conflicts with hibernate and client side programmers.

page one rankings
11 years ago

I was curious if you ever considered changing the layout of your
site? Its very well written; I love what youve got to say.
But maybe you could a little more in the way of content so people
could connect with it better. Youve got an awful
lot of text for only having 1 or 2 pictures. Maybe you could space it out better?

shyamshyre
11 years ago

Hi Mkyong,

Thanks for your Example.

Can you update the Stock Record without StockDetails getting Effected ?.

When i am trying to update Stock, A Record from StockDetail is also getting Deleted.

Please can you help me on this.

adam
11 years ago

I changed you’re code like this

try {

Stock stock = new Stock();
stock.setStockCode(“7054”);
stock.setStockName(“PADINI”);
session.save(stock);

StockDailyRecord stockDailyRecords = new StockDailyRecord();
stockDailyRecords.setPriceOpen(new Float(“1.2”));
stockDailyRecords.setPriceClose(new Float(“1.1”));
stockDailyRecords.setPriceChange(new Float(“10.0”));
stockDailyRecords.setVolume(3000000L);
stockDailyRecords.setDate(new Date());

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);
stockDailyRecords = null;

session.save(stockDailyRecords);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}
System.out.println(“Done”);

I would like to rollback stock relation update if anything goes wrong(see stockDailyRecords = null) on stockDailyRecords updates.

But it doesn’t work i expected. do you have any idea about this issue?

Dino
10 years ago
Reply to  adam
Mandar
11 years ago

Plz some one tell me How i use one to many mapping in hibernate for creation of three tables.
1.discussion(discId,queId,ansId)
2.question(queId,question,postdate)
3.answer(ansId,answer,postDate)

Thanks in advance

Plz rply its argent

John
12 years ago

Why on the Earth NONE of your example are providing SELECT, CRITERIA and so ?
You are constantly persisting bean, but this is the EASIEST to do.
Anyway, it’s my project that is stressing me.
Still it IS very hard to find something useful on the Internet when it comes about hibernate.
For e.g a: T1 -> JT1 -> T2 -> JT2 -> T3 example (where T= Table, JT=Join Table)

Adarsh
12 years ago
Reply to  John

Hi John

I was looking exactly the same what you are asking. I tried several places. This guy has described nested select in https://mkyong.com/hibernate/hibernate-fetching-strategies-examples/
It was useful for m

elias
12 years ago

thank you for example,
mm I have some difficulty to understand what is “mappedBy” means, but than Understand – that it’s StockDailyRecords fild name,
and I think that it would be great,
if you say(notice) in tutorial the meaning of “mappedBy”:
for quick dummies understanding this example =)