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

Reference

  1. Hibernate Documentation – one to many relationship
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Pingback: alkaline water()

  • Pingback: payment plan()

  • Pingback: water ionizer()

  • Pingback: Google()

  • Pingback: electrician jobs()

  • Pingback: youtube electrician vs millwright()

  • Pingback: house blue()

  • Pingback: zak?ad szklarski piotrków trybunalski()

  • Pingback: bottled alkaline water()

  • Pingback: pay per day loan plans()

  • Pingback: car parking()

  • Pingback: water ionizer machines()

  • Pingback: laan penge nu 18 aar()

  • Pingback: lan penge nu sms()

  • Pingback: parking()

  • Pingback: youporn()

  • Pingback: Business DIRECTV()

  • Pingback: tvpackages.net()

  • Pingback: Blue Coaster33()

  • giuseppe

    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

    Hello Mkyong,

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

  • naveen

    sir, why can’t upload video tutorials. They will become more useful,
    Thanks..

  • Marcin

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

    Best Regards
    Marcin

  • Luis

    Nice post, thanks!

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

    &lt;property name=&quot;hibernate.hbm2ddl.auto&quot;&gt;update&lt;/property&gt;

    … 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 = &quot;ID&quot;)
    	public int getId() {
    		return id;
    	}

    Hope it helps,

    Luis

  • Adeeb

    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

    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 ?

  • Deepa

    Hi, am new to annotations and need to some clarifications on one-to-many relationship which you explained in _http://www.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

  • Pingback: Parent child relationship hibernate | Jisku.com - Developers Network()

  • Joydeep

    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

    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

    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.

  • http://mgb.janhohmann.com/ page one rankings

    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

    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

    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?

  • Mandar

    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

  • Pingback: Hibernate Composite Keys With Annotations « Jaehoo Weblog()

  • John

    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)

  • elias

    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 =)

  • dj

    That is a great example. One question, How would you do a query to find all the StockDailyRecord records where StockDailyRecord date is equal to a specific date?

    • John

      If it’s not published, he don’t know

  • Cristian Ortiz

    this is not working neither.

     ArrayList Array = (ArrayList)Query.list();
  • Cristian Ortiz

    Hi MKYONG. how is everything. i am trap. in a HQL. i hope you can help me out. i have One to many relationship. bwt Vendedores And Clientes.

    Vendedores could have more that one Clientes.
    here is my POJOS.

    public class Vendedores implements java.io.Serializable
    {
     
        @OneToMany(fetch=FetchType.LAZY,mappedBy="Vendedor")
        private Set Cliente = new HashSet();}
    public class Clientes implements java.io.Serializable
    {
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="id",nullable=false,updatable=true,length=15,insertable=false)
        private Integer Id;
        @Basic(fetch = FetchType.EAGER)    @Column(name="idsucursal",nullable=false,updatable=true,length=5,insertable=false)
        private Integer IdSucursal;

    all i want is with HQL. with Vendedores and Clientes meeting the condition Clientes.IdSucursal = 1;
    here what i got some far.
    StringBuilder Hql = new StringBuilder(“from Vendedores V join V.Cliente C where C.IdSucursal in (:tags)”);
    Query Query = Session.createQuery(Hql.toString());
    Query.setParameterList(“tags”,new Integer[]{1});
    ArrayList Array = (ArrayList)Query.list();
    System.out.println(Array.get(0) instanceof Vendedores);
    runs very well. but Array is not InstanceOf Vendedores. what i am doing wrong. can you help me. this is driving me nuts.
    thanks a lot.

  • Cristian Ortiz

    thanks mkyong god bless you

  • Cristian Ortiz

    hey Guys excelent tutorial. i am learning hibernate. i have a question.

    in this code. is possible to store more than one stockdaily something like this.

    Set Set = new HashSet();
    Set.add(stockDailyRecords);
    Set.add(stockDailyRecords2);
    stock.setStockDailyRecords(Set);

    and when you make a save

    session.save(stock);

    store stock and the various stock daily without saves it one by one manually. help may be appreciate. thanks a lot.
    i am just a newbie. [email protected]

    • http://www.mkyong.com mkyong

      yes, just configure relationship property, and use cascade=”save-update" . See this hibernate cascade example .

      • Cristian Ortiz

        hi mkyong.

        http://www.mkyong.com/hibernate/cascade-jpa-hibernate-annotation-common-mistake/

        saves the day and it works very good.

        i have a question. do you teach courses online.. thanks a lot

        • http://www.mkyong.com mkyong

          Just wonder, how do you expect it will look like? A recorded video tutorial? Or teaching via web cam, face by face? I have some initial idea of doing it, but your inputs are truly invaluable to me.

          • Cristian Ortiz

            yep exactly. online videos a screencasting. pdf files some source code.forums. like this. and all that stuff. might be terrific..

  • Pingback: Hibernate – One-to-many relationship example (XML Mapping)()