Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit polymorphism vs Explicit polymorphism in Hibernate

I have read the O/R Mapping of Hibernate and I just can't seem to get past the part on polymorphism. According to https://docs.jboss.org/hibernate/orm/5.0/manual/en-US/html/ch05.html,

Implicit polymorphisms means that instances of the class will be returned by a query that names any superclass or implemented interface or class, and that instances of any subclass of the class will be returned by a query that names the class itself

whereas

Explicit polymorphisms means that class instances will be returned only by queries that explicitly name that class. Queries that name the class will return only instances of subclasses mapped

I just want to understand how these 2 work. Can somebody explain these terms using an example(doesn't have to be too complex) with the use of code? I would appreciate your help

like image 651
TechGeek49 Avatar asked Jun 15 '26 06:06

TechGeek49


1 Answers

First of all the org.hibernate.annotations.Entity annotation is deprecated now. You should use the @Polymorphism annotation instead.

Now, imagine that you have the following schema:

create table TST_STUDENT
(
   st_id int not null,
   st_name varchar(200),
   
   primary key (st_id)
);
insert into TST_STUDENT values (1, 'Kostya'), (2, 'Yulia'), (3, 'Borya'), (4, 'Misha');

create table TST_TEACHER
(
   tcr_id int not null,
   tcr_first_name varchar(200),
   tcr_last_name varchar(200),
   
   primary key (tcr_id)
);
insert into TST_TEACHER values (1, 'Mikhail', 'Bulgakov'), (2, 'Leo', 'Tolstoy');

and the following mapping:

public interface Person
{
   Long getId();
   
   String getName();
}

@Entity
@Table(name = "TST_STUDENT")
public class Student implements Person
{
   @Id
   @Column(name = "st_id")
   private Long id;

   @Column(name = "st_name")
   private String name;
   
   public Student()
   {
   }
   
   // getters / setters
}

and Teacher entity:

import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;


@Entity
@Table(name = "TST_TEACHER")
// @Polymorphism(type = PolymorphismType.EXPLICIT)
public class Teacher implements Person
{
   @Id
   @Column(name = "tcr_id")
   private Long id;

   @Column(name = "tcr_first_name")
   private String name;

   @Column(name = "tcr_last_name")
   private String lastName;
   
   public Teacher()
   {
   }

   // getters / setters
}

Now, if you run the following query:

List<Person> persons = em.createQuery("select p from com.your.entities.Person p", Person.class).getResultList();

you will get all rows from the TST_STUDENT table plus all rows from the TST_TEACHER table.

But, if you uncomment this line:

@Entity
@Table(name = "TST_TEACHER")
@Polymorphism(type = PolymorphismType.EXPLICIT) // now we use explicit polymorphism for the Teacher entity
public class Teacher implements Person

The mentioned above query will return only rows from the TST_STUDENT table. This is what this annotation mean.

By default, when you query a base class entity, the polymorphic query will fetch all subclasses belonging to the base type. You can even query interfaces or base classes that don’t belong to the JPA entity inheritance model.

P.S. See also this part of documentation.

like image 104
SternK Avatar answered Jun 17 '26 21:06

SternK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!