Hibernate One-to-One Mapping with JPA @OneToOne Examples

Map a one-to-one association in Hibernate 7 with JPA @OneToOne: a foreign key with @JoinColumn, a bidirectional mapping with mappedBy, a shared primary key with @MapsId and a join table, with the SQL Hibernate runs.

logo

A Hibernate one-to-one mapping links each row of one table to at most one row of another table, for example a flight booking and the boarding pass issued for it. In Hibernate and Jakarta Persistence (JPA), we declare it with the @OneToOne annotation, and Hibernate stores the link in one of three table layouts, most often a foreign key column. The entity whose table holds the link is the owning side; the other entity can map the same association with mappedBy, which makes it bidirectional (each entity can reach the other).

We use a one-to-one mapping when one record has at most one companion record, such as a user and the profile settings, or when we move rarely used columns of a wide table into a second table.

The following example uses the foreign key layout, where BoardingPass owns the booking_id column, and saves, loads and removes a pass.

// BoardingPass
@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "booking_id")
private Booking booking;

// Booking
@OneToOne(mappedBy = "booking", cascade = CascadeType.ALL, orphanRemoval = true,
    fetch = FetchType.LAZY)
private BoardingPass boardingPass;
Booking booking = new Booking("Lokesh");
booking.setBoardingPass(new BoardingPass("12A"));   // sets both sides
em.persist(booking);                   // insert into booking (passenger,id) values (?,?)
                                       // insert into boarding_pass (booking_id,seat,id) values (?,?,?)

BoardingPass pass = em.find(BoardingPass.class, passId);   // 1 select, booking is a lazy proxy
Booking loaded = em.find(Booking.class, bookingId);         // 2 selects, LAZY is ignored on the mappedBy side
booking.setBoardingPass(null);         // delete from boarding_pass where id=?

Notice that loading the pass runs one SELECT, whereas loading the booking runs two, because Hibernate ignores LAZY on the mappedBy side.

Next, we compare the three table layouts and build each of them. After that, we look at fetching and cascades, and answer the common questions about unique constraints and lazy loading.

1. How Is a One-to-One Association Stored?

A database has no one-to-one column type, so a one-to-one association is a foreign key that may appear only once, which the database enforces with a unique constraint or a primary key. JPA can place that key in three different places.

Three table layouts for booking and boarding_pass: a foreign key column booking_id in boarding_pass; a shared primary key where boarding_pass.booking_id is both the primary key and the foreign key; a join table booking_boarding_pass holding booking_id and boarding_pass_id
The same association in three table layouts. Only the join table keeps both entity tables free of foreign key columns.

Each layout has its own annotation and its own cost when we save or load the pair.

Foreign keyShared primary keyJoin table
Annotations@OneToOne + @JoinColumn@OneToOne + @MapsId@OneToOne + @JoinTable
Extra columnsbooking_id in boarding_pass, uniqueNone, booking_id replaces idA third table with two keys
Inserts to save both223
Load the pass of a bookingQuery on booking_idem.find() with the booking idJoin through the link table
Good fitMost cases, bidirectional accessA child that never exists without its parentAn optional link that is set later

In Java, a foreign key @OneToOne looks like a @ManyToOne. The difference is in the table. Hibernate makes the join column of a @OneToOne unique, so the database rejects a second boarding pass for the same booking (see FAQ 3.2).

2. One-to-One Mapping Example

We build the example with Hibernate 7.4, Java 25 and an H2 in-memory database. Each variant maps the same two tables, booking and boarding_pass, and runs against its own database. The complete project on GitHub prints the SQL of every step and checks the results with 17 JUnit tests (mvn -q compile exec:java, mvn test).

2.1. Domain Model

A passenger books a flight, and at check-in the airline issues one boarding pass for that booking. The booking exists before the pass, so Booking is the parent and BoardingPass is the child. Both entities start with a generated id and one plain field.

// Booking
@Id
@GeneratedValue
private Long id;
private String passenger;      // "Lokesh"

// BoardingPass
@Id
@GeneratedValue
private Long id;
private String seat;           // "12A"

2.2. Foreign Key Association With @JoinColumn

In this layout, the child table holds the foreign key. The annotation @JoinColumn names that column, and the field that carries it becomes the owning side.

@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "booking_id")
private Booking booking;

Hibernate creates booking_id as unique, and as not null because of optional = false.

create table booking (id bigint not null, passenger varchar(255), primary key (id))
create table boarding_pass (booking_id bigint not null unique, id bigint not null, seat varchar(255), primary key (id))
alter table if exists boarding_pass add constraint FK... foreign key (booking_id) references booking

With this field alone, the association is unidirectional, so a boarding pass knows its booking, but a booking does not know its pass.

2.3. Bidirectional One-to-One With mappedBy

To reach the pass from the booking, we add a @OneToOne field to Booking with mappedBy. Its value is the name of the owning field, booking. We also add a helper method that sets both fields, because Java objects do not update each other.

@OneToOne(mappedBy = "booking", cascade = CascadeType.ALL, orphanRemoval = true,
    fetch = FetchType.LAZY)
private BoardingPass boardingPass;

public void setBoardingPass(BoardingPass pass) {
  if (pass == null) {
    if (this.boardingPass != null) {
      this.boardingPass.setBooking(null);
    }
  } else {
    pass.setBooking(this);
  }
  this.boardingPass = pass;
}

Only the owning side is written to the database. The mappedBy field has no column of its own.

Java entities and tables side by side: BoardingPass.booking with @JoinColumn writes the booking_id column of boarding_pass; Booking.boardingPass with mappedBy has no column and reads boarding_pass.booking_id
BoardingPass.booking writes booking_id. Booking.boardingPass is filled by reading that same column.

Saving the booking also saves the pass, because of cascade = CascadeType.ALL.

emf.runInTransaction(em -> {
  Booking booking = new Booking("Lokesh");
  booking.setBoardingPass(new BoardingPass("12A"));
  em.persist(booking);
});   // insert into booking (passenger,id) values (?,?)
      // insert into boarding_pass (booking_id,seat,id) values (?,?,?)

2.4. Shared Primary Key With @MapsId

With @MapsId, the child has no id of its own. Its primary key column is also the foreign key to the parent, and Hibernate copies the parent’s id into it. So @Id has no @GeneratedValue here.

@Id
private Long id;

@OneToOne(fetch = FetchType.LAZY)
@MapsId
@JoinColumn(name = "booking_id")
private Booking booking;
create table boarding_pass (booking_id bigint not null, seat varchar(255), primary key (booking_id))
alter table if exists boarding_pass add constraint FK... foreign key (booking_id) references booking

The Booking entity needs no boardingPass field, because the booking id is also the id of its pass.

Booking booking = new Booking("Lokesh");
em.persist(booking);                                 // booking.getId() = 1
BoardingPass pass = new BoardingPass(booking, "12A");
em.persist(pass);                                    // pass.getId() = 1
// insert into booking (passenger,id) values (?,?)
// insert into boarding_pass (seat,booking_id) values (?,?)

BoardingPass found = em.find(BoardingPass.class, bookingId);   // select ... from boarding_pass where booking_id=?

This unidirectional @MapsId mapping is the recommended choice over a bidirectional one, because it avoids the extra query described in section 2.6. A boarding pass never exists without its booking, so the shared key fits our example.

2.5. Join Table With @JoinTable

A join table (link table) stores the pair of ids in a third table. Neither booking nor boarding_pass gets a foreign key column, so a booking without a pass leaves no NULL behind.

@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "booking_boarding_pass",
    joinColumns = @JoinColumn(name = "booking_id"),
    inverseJoinColumns = @JoinColumn(name = "boarding_pass_id"))
private BoardingPass boardingPass;
create table booking_boarding_pass (boarding_pass_id bigint not null unique, booking_id bigint not null, primary key (booking_id))

We save Lokesh with a pass and Alex, who has not checked in yet, without one. Only Lokesh gets a row in the link table.

insert into boarding_pass (seat,id) values (?,?)
insert into booking (passenger,id) values (?,?)
insert into booking_boarding_pass (boarding_pass_id,booking_id) values (?,?)
insert into booking (passenger,id) values (?,?)

Loading a booking joins three tables.

select b1_0.id,b1_0.passenger,b1_1.boarding_pass_id,bp1_0.id,bp1_0.seat
from booking b1_0
left join booking_boarding_pass b1_1 on b1_0.id=b1_1.booking_id
left join boarding_pass bp1_0 on bp1_0.id=b1_1.boarding_pass_id
where b1_0.id=?

2.6. EAGER vs LAZY Fetching

The fetch type decides when Hibernate loads the associated entity. The default for @OneToOne is FetchType.EAGER. Hibernate loads the booking every time it loads a boarding pass. The call em.find() loads it with a join, but a JPQL query runs one more SELECT per row, which is the N+1 query problem. For example, a gate screen that lists 200 boarding passes runs 201 queries.

@OneToOne
@JoinColumn(name = "booking_id")
private Booking booking;
select bp1_0.id,bp1_0.booking_id,bp1_0.seat from boarding_pass bp1_0
select b1_0.id,bp1_0.id,bp1_0.seat,b1_0.passenger from booking b1_0 left join boarding_pass bp1_0 on ... where b1_0.id=?
select b1_0.id,bp1_0.id,bp1_0.seat,b1_0.passenger from booking b1_0 left join boarding_pass bp1_0 on ... where b1_0.id=?
select b1_0.id,bp1_0.id,bp1_0.seat,b1_0.passenger from booking b1_0 left join boarding_pass bp1_0 on ... where b1_0.id=?

With fetch = FetchType.LAZY on the owning side, Hibernate reads only the boarding_pass row and puts a proxy (a placeholder object) in the booking field, and the proxy runs its SELECT only when we call its first getter.

BoardingPass pass = em.find(BoardingPass.class, passId);       // 1 select
boolean loaded = Hibernate.isInitialized(pass.getBooking());   // false
String passenger = pass.getBooking().getPassenger();           // "Lokesh", 2nd select

The mappedBy side behaves differently, because the booking row has no column that tells Hibernate whether a pass exists. Hibernate must decide between null and a proxy when it loads the booking, so it queries boarding_pass right away.

Two flows: em.find(BoardingPass.class, id) runs one select, sees booking_id in the row and creates a proxy; em.find(Booking.class, id) runs a select on booking, cannot tell if a pass exists, and runs a second select on boarding_pass where booking_id equals the id
The owning side has the foreign key, so a proxy is enough. The mappedBy side has no column, so Hibernate runs a second query.
select b1_0.id,b1_0.passenger from booking b1_0 where b1_0.id=?
select bp1_0.id,bp1_0.booking_id,bp1_0.seat from boarding_pass bp1_0 where bp1_0.booking_id=?

On the mappedBy side, Hibernate ignores FetchType.LAZY. The JPA specification calls LAZY a hint, and this is a case where Hibernate cannot follow it. FAQ 3.4 lists the ways around it.

2.7. Cascade, orphanRemoval and optional = false

The attribute cascade passes an operation from the parent to the child, and orphanRemoval deletes a child that its parent no longer references. The attribute optional = false says that the association can never be null. Each setting maps to concrete SQL or to an error.

SettingCodeResult
cascade = CascadeType.ALLem.persist(booking)Inserts the booking, then the pass
cascade = CascadeType.ALLem.remove(booking)delete from boarding_pass, then delete from booking
orphanRemoval = truebooking.setBoardingPass(null)delete from boarding_pass where id=?
optional = falseem.persist(new BoardingPass(“14C”))PropertyValueException, no INSERT

Without optional = false, the booking_id column is nullable, so Hibernate saves a pass without a booking. With it, Hibernate checks the field before the INSERT.

org.hibernate.PropertyValueException: not-null property references a null or transient value for entity com.howtodoinjava.hibernate.onetoone.foreignkey.BoardingPass.booking

See also Hibernate orphan removal and JPA cascade types

3. One-to-One Mapping FAQs

3.1. Which Side Should Own the Foreign Key?

We put the foreign key on the entity that depends on the other one, here BoardingPass, and the dependent side gets the most out of the column.

  • The column can be NOT NULL, because a pass always has a booking. A boarding_pass_id in booking would be NULL until check-in.
  • LAZY works on the owning side, so loading a pass does not load its booking.
  • The child can switch to @MapsId later without changing the booking table.

3.2. Does @OneToOne Add a Unique Constraint?

Yes. Hibernate generates the join column as unique (booking_id bigint not null unique), and the join table gets boarding_pass_id … unique plus a primary key on booking_id. A second pass for the same booking fails at commit.

jakarta.persistence.RollbackException: Error while committing the transaction [could not execute statement [Unique index or primary key violation: "PUBLIC.CONSTRAINT_8 INDEX PUBLIC.CONSTRAINT_INDEX_8 ON PUBLIC.BOARDING_PASS(BOOKING_ID NULLS FIRST) VALUES ( /* 1 */ CAST(1 AS BIGINT) )"; ...]]

If we create the schema with our own scripts, we add the unique constraint ourselves.

3.3. What Is the Difference Between @MapsId and @PrimaryKeyJoinColumn?

Both annotations join the two tables on their primary keys, but only @MapsId fills in the child’s id. The annotation @PrimaryKeyJoinColumn is the older JPA 1.0 style, and with it we copy the id by hand.

@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
private BoardingPass boardingPass;
// 1. Without the id
booking.setBoardingPass(new BoardingPass("12A"));
em.persist(booking);               // IdentifierGenerationException

// 2. With the id copied by hand
em.persist(booking);
pass.setId(booking.getId());
booking.setBoardingPass(pass);     // insert into boarding_pass (seat,id) values (?,?)
org.hibernate.id.IdentifierGenerationException: Identifier of entity 'com.howtodoinjava.hibernate.onetoone.primarykey.BoardingPass' must be manually assigned before calling 'persist()'

The two annotations also produce different schemas.

@MapsId@PrimaryKeyJoinColumn
Child idCopied from the parentSet by hand
Foreign key constraintCreatedNot created by Hibernate 7.4 in this mapping
RecommendedYesOnly for old code

3.4. Why Is My LAZY @OneToOne Loaded Anyway?

In most cases, the LAZY field is on the mappedBy side, where Hibernate has no column to decide between null and a proxy (see section 2.6). Each option in the table avoids the extra query for a booking and its pass.

OptionSQL
join fetch in the query1 select with join boarding_pass
@MapsId, no field on Booking, then em.find(BoardingPass.class, bookingId)1 select on boarding_pass, booking stays a proxy
Move the foreign key to the side we load mostProxy on that side, extra select on the other
Booking booking = em.createQuery("select b from Booking b join fetch b.boardingPass where b.id = :id", Booking.class)
    .setParameter("id", bookingId)
    .getSingleResult();
// select b1_0.id,bp1_0.id,bp1_0.booking_id,bp1_0.seat,b1_0.passenger from booking b1_0
//   join boarding_pass bp1_0 on b1_0.id=bp1_0.booking_id where b1_0.id=?

One more option is bytecode enhancement, which is a build step that changes the entity classes so Hibernate can load single fields lazily. Without enhancement, Hibernate uses proxies for lazy loading.

4. Conclusion

A @OneToOne mapping stores its link as a unique foreign key with @JoinColumn in most cases. The alternatives are a shared primary key with @MapsId and a link table with @JoinTable. The owning side holds the column and writes it, while mappedBy makes the association bidirectional without a new column. We set LAZY on the owning side and remember that the mappedBy side always loads its child. When the child never exists without its parent, we prefer @MapsId.

5. References

Happy Learning !!

Source Code on Github

Leave a Comment

  1. Hi Lokesh,
    This article is very good, your way explanation also very good. I studied various articles on One to One and i found total 6 technical ways to define One to One mapping (all information is not defined any where, based on understanding on articles, I defined as below ways)
    1. Unidirectional with Foreign Key
    2. Unidirectional with Shared Primary Key.
    3. Bidirectional with Foreign Key
    4. Bidirectional with Shared Primary Key.
    5. Bidirectional with MapsId
    6. Join Table.

    Requesting could you please clarify my doubt, how many ways can we define One to One mapping ?

  2. Thanks for this Article.. I’m having query related to lazy fetching.. how to achieve the same using the above @OneToOne mapping example. Please can you help on that..

  3. Wonderful explanation!
    You wrote a great article. Earlier I spent a lot of time studying this topic but I did not understand it. Thank you!

  4. User.java
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy="user")
    private Set<Address> userAddresses = new HashSet<Address>();
    
    Address.java
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="UserID")
    private User user;
    

    In OneToMany relation, the many side is the owner of the relation right ? but by specifying mappedBy=user we are saying that User is the owning entity.why?
    Can you please explain the above concept ?

    for bi directional rules check oracle documentation:https://docs.oracle.com/cd/E19798-01/821-1841/bnbqj/index.html

  5. Hi. I have a question about @OneToOne(cascade = CascadeType.ALL) when you implement “Using a common join table”. In this case, the cascade is on the side of EmployeeEntity. But I wonder, if the mappedby is in AccountEntity, then EmployeeEntity has a foreign key in AccountEntity, and I expect that removing, for example, a record from AccountEntity, the removal will be cascaded also in EmployeeEntity. So, shouldn’t the cascade be on the side of AccountEntity, where you also have the mapped by? Thanks for these great tutorials.

    Valentino

  6. In your “mappedBy” example no foreign key relationship maintained by EmployeeEntity. Even there is no relationship between both table . You can cross verify your sql query above. i.e.

    Hibernate: insert into ACCOUNT (ACC_NUMBER) values (?)
    Hibernate: insert into Employee (ACCOUNT_ID, EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?, ?)

    there is no update query for foreign key.

    Please clarify?

    I think @JoinColumn instead of @PrimaryKeyJoinColumn is better choice.

  7. Hi,

    I tried foreign key column model, my question is why hibernate creates join table ’employee_acccount’ and have no use in one to one association. can any one clear my doubt?

  8. Superb tutorial, was of great help to implement the one to one relationships in my application’s datamodel. Thanks a lot, keep rocking.

  9. thanks , good explanation. Can you please modify the same example to add one new column in newly created table.

      • thanks but I got How to do it…
        I am pasting my example here…

        1) AccountEntity.java

        package com.hbm;
        
        import java.io.Serializable;
        import java.util.HashSet;
        import java.util.Set;
        
        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.GenerationType;
        import javax.persistence.Id;
        import javax.persistence.OneToMany;
        import javax.persistence.Table;
        import javax.persistence.UniqueConstraint;
        
        
        @Entity(name = "JoinTableAccountEntity")
        @Table(name = "ACCOUNT", uniqueConstraints = {
        @UniqueConstraint(columnNames = "ID")})
        public class AccountEntity implements Serializable
        {
        
           private static final long serialVersionUID = -6790693372846798580L;
        
           @Id
           @GeneratedValue(strategy = GenerationType.IDENTITY)
           @Column(name = "ID", unique = true, nullable = false)
           private Integer accountId;
        
           @Column(name = "ACC_NUMBER", unique = true, nullable = false, length = 100)
           private String accountNumber;
           
           public AccountEntity( String accountNumber) {
        	super();
        	this.accountNumber = accountNumber;
        }
        
        @OneToMany(mappedBy = "accountentity")
           private Set empaccdetail= new HashSet();
        
           public Set getEmpaccdetail() {
        	return empaccdetail;
        }
        
        public void setEmpaccdetail(Set empaccdetail) {
        	this.empaccdetail = empaccdetail;
        }
        
        public Integer getAccountId() {
               return accountId;
           }
        
           public void setAccountId(Integer accountId) {
               this.accountId = accountId;
           }
        
           public String getAccountNumber() {
               return accountNumber;
           }
        
           public void setAccountNumber(String accountNumber) {
               this.accountNumber = accountNumber;
           }
        }
        

        2)EmployeeEntity.java

        package com.hbm;
        import java.io.Serializable;
        import java.util.Set;
        
        import javax.persistence.CascadeType;
        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.GenerationType;
        import javax.persistence.Id;
        import javax.persistence.JoinColumn;
        import javax.persistence.JoinTable;
        import javax.persistence.OneToMany;
        import javax.persistence.Table;
        import javax.persistence.UniqueConstraint;
         
        @Entity
        @Table(name = "Employee", uniqueConstraints = {
        @UniqueConstraint(columnNames = "ID"),
        @UniqueConstraint(columnNames = "EMAIL") })
        public class EmployeeEntity implements Serializable
        {
            private static final long serialVersionUID = -1798070786993154676L;
         
            @Id
            @GeneratedValue(strategy = GenerationType.IDENTITY)
            @Column(name = "ID", unique = true, nullable = false)
            private Integer employeeId;
         
            public EmployeeEntity(String email, String firstName,
        			String lastName) {
        		super();
        		this.email = email;
        		this.firstName = firstName;
        		this.lastName = lastName;
        	}
        
        	@Column(name = "EMAIL", unique = true, nullable = false, length = 100)
            private String email;
         
            @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
            private String firstName;
         
            @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
            private String lastName;
         
            @OneToMany( mappedBy="accountentity")
            private Set empaccdetail;
         
            public Integer getEmployeeId() {
                return employeeId;
            }
         
            public void setEmployeeId(Integer employeeId) {
                this.employeeId = employeeId;
            }
         
            public String getEmail() {
                return email;
            }
         
            public void setEmail(String email) {
                this.email = email;
            }
         
            public String getFirstName() {
                return firstName;
            }
         
            public void setFirstName(String firstName) {
                this.firstName = firstName;
            }
         
            public String getLastName() {
                return lastName;
            }
         
            public void setLastName(String lastName) {
                this.lastName = lastName;
            }
        
        	public Set getEmpaccdetail() {
        		return empaccdetail;
        	}
        
        	public void setEmpaccdetail(Set empaccdetail) {
        		this.empaccdetail = empaccdetail;
        	}
        }
        

        3)EmpAcc.java (bean for joined table)

        package com.hbm;
        
        import javax.persistence.CascadeType;
        import javax.persistence.Column;
        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.Id;
        import javax.persistence.JoinColumn;
        import javax.persistence.ManyToOne;
        import javax.persistence.Table;
        
        @Entity
        @Table(name = "Emp_Acc")
        public class EmpAcc 
        {
        	@Id
        	 @GeneratedValue
        	@Column(name="EMP_ACC_ID")
        		private long emp_acc_id;
        	
        	@ManyToOne(cascade = CascadeType.ALL)
        	    @JoinColumn(name = "EID")  
        	    private EmployeeEntity employeeentity;
        	 
        	  @ManyToOne(cascade = CascadeType.ALL)
        	    @JoinColumn(name = "AID")
        	    private AccountEntity accountentity;
        	    public long getEmp_acc_id() {
        		return emp_acc_id;
        	}
        	public void setEmp_acc_id(long emp_acc_id) {
        		this.emp_acc_id = emp_acc_id;
        	}
        	public EmployeeEntity getEmployeeentity() {
        		return employeeentity;
        	}
        	public void setEmployeeentity(EmployeeEntity employeeentity) {
        		this.employeeentity = employeeentity;
        	}
        	public AccountEntity getAccountentity() {
        		return accountentity;
        	}
        	public void setAccountentity(AccountEntity accountentity) {
        		this.accountentity = accountentity;
        	}
        	public int getBalance() {
        		return balance;
        	}
        	public void setBalance(int balance) {
        		this.balance = balance;
        	}
        		private int  balance;
        	
        
        }
        

        4)MainClass.java

        package com.hbm;
        
        import org.hibernate.Session;
        import org.hibernate.cfg.Configuration;
         
        public class TestJoinTable
        {
            public static void main(String[] args)
            {
                Session session = new Configuration().configure("com/hbm/hibernate.cfg.xml").buildSessionFactory().openSession();
                		session.beginTransaction();
         
                		EmployeeEntity emp=new EmployeeEntity("fdsgf@fgf"," jffksjf"," fdlskf");
                		
                		AccountEntity acc=new AccountEntity("245");
                		        		
                		EmpAcc empAcc=new EmpAcc();
                		empAcc.setEmployeeentity(emp);
                		empAcc.setAccountentity(acc);
                		empAcc.setBalance(3555);
                	
           session.save(empAcc);
            System.out.println("saved ");
                session.getTransaction().commit();
        
            }
        }
        

        In the above example balance is the new column.

  10. your example is good one but i want one additional column in a newly created join table (employee_account) Can you please modify this example to add extra column

  11. Hi ,
    Can you please elobarate on mappedBy attribute.
    Could not understand, even I searched so many sites.
    mappedby definition says ‘I am not the owner side and mapped by other entity’
    From the given example(Employee and Account) with below code.
    @OneToOne(mappedBy=”account”)
    private EmployeeEntity employee;
    Who is not the owner? and who is Owner and what is does actually.
    Please explains

  12. Was learning Hibernate and went through so many tutorials online. Completely misunderstood the functionality of mappedBy till i came across this article. Good stuff guys, keep up the good work (Y)

  13. i need a help,
    we have a list as field to store it in data base,
    for this we have to use hibernate annotations mapping class(no hibernate mapping file should be used), pojo class object contains some fields as List, those fileds will be inserted into db as string by mapping class. if possible for you, give an example

  14. HI Lokesh,
    Good after noon,

    Currently i am working with hibernate 3. i have been trying to develop a simple hibernate project with one to many relationship.every thing is fine but i am getting error like. i have placed cfg.xml file under src folder.is correct. why i am getting error. please suggest me. as soon as…..

    log4j:WARN No appenders could be found for logger (org.hibernate.cfg.annotations.Version).
    log4j:WARN Please initialize the log4j system properly.
    Initial SessionFactory creation failed.org.hibernate.HibernateException: could not find file: hibernate.cgf.xml
    Exception in thread “main” java.lang.ExceptionInInitializerError
    at com.hib.pro.HibernateUtil.buildSessionFactory(HibernateUtil.java:23)
    at com.hib.pro.HibernateUtil.(HibernateUtil.java:11)
    at com.hib.pro.TestForeignKeyAssociation.main(TestForeignKeyAssociation.java:19)
    Caused by: org.hibernate.HibernateException: could not find file: hibernate.cgf.xml
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1462)
    at com.hib.pro.HibernateUtil.buildSessionFactory(HibernateUtil.java:18)
    … 2 more
    Caused by: java.io.FileNotFoundException: hibernate.cgf.xml (The system cannot find the file specified)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.(FileInputStream.java:106)
    at org.hibernate.cfg.Configuration.configure(Configuration.java:1459)
    … 3 more

    • Usually src folders have filters which cause to generate only .class files in target folder or classes folder. Copy the file in resources folder. The important thing is that file should be present in target folder (war file).

  15. Hi Lokesh,

    Good Work. But I see a flaw in the DB design of your “Using foreign key association”. In the Employee Table one can have one account shared by the multiple employees which does not make it one to one but many to one. For that you need to put Unique constraint on Account Id column in Employee Table. Please clarify.

    • Abhi, you are right. It should be implemented this way. But, also that’s not core concept for this tutorial. Mixing concepts in single post, sometimes push the core concept in back seat. Which i did not wanted to do, otherwise in any code review session, I can myself blew this code. [:-)]

Comments are closed.

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.