Skip to content
geeksforgeeks
  • Tutorials
    • Python
    • Java
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
    • Practice Coding Problems
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Java Tutorial
  • Java Spring
  • Spring Interview Questions
  • Java SpringBoot
  • Spring Boot Interview Questions
  • Spring MVC
  • Spring MVC Interview Questions
  • Java Hibernate
  • Hibernate Interview Questions
  • Advance Java Projects
  • Java Interview Questions
Open In App
Next Article:
Why @OneToMany Does not Work with Inheritance in Hibernate?
Next article icon

Why @OneToMany Does not Work with Inheritance in Hibernate?

Last Updated : 11 Oct, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Hibernate, a popular ORM (Object-Relational Mapping) framework, helps map Java classes to database tables. While Hibernate supports @OneToMany relationships, developers may face issues when inheritance is introduced in these relationships. This article will explore why @OneToMany relationships do not work smoothly with inheritance and what solutions can be applied.

In Hibernate, the @OneToMany annotation defines one-to-many relationships between entities. A simple use case of @OneToMany works as expected, but the problem arises when inheritance is involved.

Let's start by looking at a simple scenario.

Example: Author and Book Relationship

Author.java

@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Primary key

// One-to-many relationship to Book, mapped by 'author' field in Book
@OneToMany(mappedBy = "author")
private List<Book> books;

// Getters and setters
}
  • The Author entity has a one-to-many relationship with Book.
  • The @OneToMany annotation is used to define this relationship, and the mappedBy attribute refers to the author field in the Book class.

Book.java

@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Primary key

// Many-to-one relationship to Author
@ManyToOne
@JoinColumn(name = "author_id") // Join column for author foreign key
private Author author;

// Getters and setters
}
  • The Book class has a many-to-one relationship with Author.
  • The @ManyToOne annotation defines the relationship, and @JoinColumn sets up the foreign key column (author_id) in the Book table.

In this example, the @OneToMany relationship between Author and Book works without any problems because there’s no inheritance.

Now, let's introduce inheritance and see where issues arise.

Inheritance in Hibernate

Hibernate supports different inheritance strategies for mapping Java classes to database tables:

  • Single Table (SINGLE_TABLE): All classes in the hierarchy are stored in one table.
  • Joined Table (JOINED): Each class has its own table.
  • Table per Class (TABLE_PER_CLASS): Each class has its own table, without any inheritance relationship between them.

Scenario with Inheritance

Let’s introduce an inheritance hierarchy for Publication, where Book and Magazine are subclasses.

Publication.java

@Entity
@Inheritance(strategy = InheritanceType.JOINED) // Use JOINED strategy for inheritance
public class Publication {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Primary key for Publication

// Common properties for all publications
private String title;

// Getters and setters
}
  • Publication is the base class.
  • The @Inheritance annotation with the JOINED strategy tells Hibernate to map subclasses to separate tables and link them to the parent table.

Book.java

@Entity
public class Book extends Publication {
// Book-specific properties
private String isbn;

// Getters and setters
}
  • Book inherits from Publication and has additional properties (isbn).
  • The inheritance is handled by Hibernate, but no specific annotations are needed for Book since it inherits from Publication.

Magazine.java

@Entity
public class Magazine extends Publication {
// Magazine-specific properties
private String issueNumber;

// Getters and setters
}
  • Magazine is another subclass of Publication, and it adds its own properties (issueNumber).
  • Just like Book, Magazine is part of the inheritance hierarchy.

Now, let's define the Library entity that contains a collection of Publication (including both Book and Magazine).

Library.java:

@Entity
public class Library {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Primary key for Library

// One-to-many relationship to Publication, which is a parent class in the hierarchy
@OneToMany
private List<Publication> publications;

// Getters and setters
}
  • Library contains a list of Publication, which could hold either Book or Magazine.
  • The @OneToMany annotation is used to define this relationship with Publication.

Problem with @OneToMany and Inheritance

When we try to use a @OneToMany relationship with polymorphic entities (like Publication, Book, and Magazine), Hibernate has trouble handling the polymorphic nature of the collection.

  • Polymorphic Collections: Hibernate cannot determine which subclass of Publication (Book or Magazine) to load when retrieving Library.publications. This leads to errors during data retrieval.
  • Lazy Loading: When lazy-loading is used with a polymorphic collection, Hibernate might struggle to create proxies for the child classes, resulting in incomplete data.
  • Cascade Operations: Cascading operations such as PERSIST or REMOVE may not propagate correctly in a polymorphic collection, leading to data inconsistency.

Why Does This Happen?

The primary reason is that Hibernate expects collections to map to a single table. With polymorphism, different subclasses are stored in different tables, which complicates the query mechanism. Hibernate cannot easily infer which subclass instances to return from the Library.publications collection.

Solutions and Workarounds

To resolve these issues, several strategies can be employed.

1. Use @MappedSuperclass for Common Parent Class

If we do not need to persist instances of the parent class (Publication) directly, use @MappedSuperclass. This way, Publication won’t be treated as an entity, and you can avoid the complications of inheritance.

@MappedSuperclass
public abstract class Publication {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Common ID for all subclasses

private String title; // Common title field

// Getters and setters
}
  • With @MappedSuperclass, Publication becomes an abstract class and won’t have its own table.
  • Only Book and Magazine will have their own tables, simplifying the @OneToMany mapping.

2. Use Explicit Queries to Handle Polymorphic Collections

Instead of relying on Hibernate to automatically handle polymorphism, you can define specific queries for each subclass. For example, retrieving all Books in a Library:

SELECT b FROM Book b WHERE b.library.id = :libraryId

By explicitly querying for subclasses (Book, Magazine), you take control of the query mechanism and avoid the pitfalls of polymorphic collections.

3. Avoid Polymorphic Collections

We can split the polymorphic collection into multiple homogeneous collections. For example:

For example:

@Entity
public class Library {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Primary key

// Separate collections for Books and Magazines
@OneToMany
private List<Book> books;

@OneToMany
private List<Magazine> magazines;

// Getters and setters
}

This approach separates Book and Magazine collections, which eliminates the polymorphism problem and simplifies the relationship management.

4. Use SINGLE_TABLE Inheritance with @DiscriminatorColumn

We can simplify inheritance mapping by using the SINGLE_TABLE strategy and adding a discriminator column to distinguish between subclasses.

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "publication_type") // Column to distinguish subclass type
public class Publication {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Common ID for all types of publications

private String title;

// Getters and setters
}
  • The SINGLE_TABLE strategy stores all entities in one table with a publication_type column to identify the subclass.
  • This approach avoids the need for joins or multiple tables, simplifying the @OneToMany relationship

Conclusion

The issues with @OneToMany and inheritance in Hibernate stem from the complexities of handling polymorphic collections across multiple tables. Hibernate struggles to manage relationships when inheritance is involved, but by applying workarounds like @MappedSuperclass, explicit queries, or inheritance strategies like SINGLE_TABLE, you can resolve these problems effectively.

By carefully choosing the mapping strategy and relationship design, you can avoid the challenges associated with @OneToMany and inheritance in Hibernate.


Next Article
Why @OneToMany Does not Work with Inheritance in Hibernate?

K

kadambalamatclo
Improve
Article Tags :
  • Advance Java
  • Java-Hibernate
  • Hibernate Mapping

Similar Reads

    Hibernate - Inheritance Mapping
    The inheritance hierarchy can be seen easily in the table of the database. In Hibernate we have three different strategies available for Inheritance Mapping Table Per HierarchyTable Per Concrete classTable Per Subclass Hierarchy can be diagrammatically seen easily.   In this article let us see about
    5 min read
    Inheritance Hierarchies in DBMS
    Inheritance Hierarchies are crucial to building a structured and well-organized database. It is comparable to the idea of inheritance found in object-oriented programming languages. The main ideas of inheritance hierarchies in database management systems (DBMS) will be covered in this article, along
    7 min read
    Hibernate - @Inheritance Annotation
    The @Inheritance annotation in JPA is used to specify the inheritance relation between two entities. It is used to define how the data of the entities in the hierarchy should be stored in the database. The @Inheritance  annotation provides us with benefits to reduce code complexity by creating a bas
    6 min read
    Rich Domain Model with Hibernate
    Rich Domain Model in the context of software development and Hibernate is the model where the business logic is encapsulated directly within the domain objects, rather than being separated into the services or other layers. It can allow the domain model to enforce the business rules and ensure data
    4 min read
    When to Use @JoinColumn Annotation in Hibernate?
    The @JoinColumn annotation in Hibernate is used to specify the mapping of a foreign key column in a relationship between two entities. The @JoinColumn annotation is applied on the owning side of the association to define the foreign key column name and other attributes which are related to the join
    3 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences