Hibernate polymorphism

后端 未结 2 1645
醉梦人生
醉梦人生 2021-02-04 08:47

This is a Hibnerate polymorphism question and a data model design question; they are intertwingled. I\'ve used Hibernate in the past, and have enjoyed it, but sometimes I find

相关标签:
2条回答
  • 2021-02-04 09:03

    This is absolutely possible. You could associate the notes with the abstract Fruit class instead of repeating them in each of the implementations:

    @Entity
    @Inheritance
    public abstract class Fruit {
       private Set<Note> notes;
       ...
    
       @OneToMany(cascade = CascadeType.ALL, mappedBy = "fruit")
       public Set<Note> getNotes() {
           return notes;
       }
    }
    
    @Entity
    public class Apple extends Fruit {
       ...
    }
    
    
    @Entity
    public class Orange extends Fruit {
       ...
    }
    
    @Entity
    public class Note {
       private String theNote;
    
       @ManyToOne
       private Fruit fruit;
       ...
    }
    

    Ét voilà!

    -- Addition based on comment: JPA provides multiple strategies for dealing with inheritance. The relevant section in the Java EE tutorial should help you get started.

    Basically, your options are:

    • Storing everything in one table and using a discriminator column to know which row is which type
    • Storing each concrete class (Apple and Orange) in a separate table
    • Having a common Fruit table with a discriminator column, and Apple and Orange tables with a foreign key to the Fruit table

    Another edit: Noticed this is a Hibernate, not a JPA question. Does not make too much of a difference, though, as the options are the same. Here's the relevant section in the Hibernate docs.

    0 讨论(0)
  • 2021-02-04 09:10

    This pattern is very common in Hibernate based datalayers. How it works internally is heavily based on which inheritance strategy is used.

    When using table per class or table per subclass inheritance, a table for every subclass/class will be created. For example, in your case, you would have a table Fruit and two tables Apple and Orange, with foreign key references between Fruit and Apple/Orange. When requesting a single fruit (be it apple or orange) by ID, Hibernate will outer join the Fruit table with the Apple and Orange table. Each row will be transformed into an Apple or Orange depending on from which table the fields were retrieved.

    Another possibility is to use discriminators. A single table Fruit will be used which will contain a discriminator field (ex. fruit_type taking values apple and orange). Depending on the value of this field, Hibernate will determine whether the corresponding object is an Apple or an Orange.

    In your case, in the case of eager loading, when Hibernate loads the Note object it will eagerly fetch the corresponding Fruit and populate the fruit field with an instance of Apple or Orange accordingly.

    In the case of lazy fetching, the fruit field will be a proxy implementing the Fruit interface. Until the actual fruit field is loaded its type is undetermined.

    Hope this answers some of your queries.

    0 讨论(0)
提交回复
热议问题