Search code examples
javahibernatehql

How to SELECT the stronger entity which is a @MappedSuperclass by the weaker entity's id using HQL?


I have the following mapped superclass which serves as a superclass to other 3 classes:

@MappedSuperclass
public abstract class Donation {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    //other irrelevant attributes

    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY)
    private List<Voucher> vouchers;

    //getters and setters
}

The other classes extending from Donation are Adoption, Appointment and Exam. This relationship created the following associative entities towards Voucher: adoption_vouchers, appointment_vouchers and exam_vouchers.

The current problem is that now I have to list all Voucher together with it's Donation entity. Since I do not have specified the donation relationship in the voucher class (because it could represent any of the 3 classes mentioned, and I can't relate to a @MappedSuperclass), is there a way I achieve it using HQL (retrieving something like a Map<Donation, Voucher>), or maybe minor changes in my structure to retrieve this information?


Solution

  • HQL could look like this with below model SELECT a.vouchers FROM Adoption a;

    public enum DonationType {
      ADOPTION, APPOINTMENT, EXAM;
    }
    
    @MappedSuperclass
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="type", 
      discriminatorType = DiscriminatorType.STRING)
    public abstract class Donation {
         @Enumerated(EnumType.STRING)
         private DonationType type;
    
         @JsonIgnore
         @OneToMany(fetch = FetchType.LAZY)
         private List<Voucher> vouchers;
    }
    
    @Entity
    @DiscriminatorValue(DonationType.ADOPTION)
    public class Adoption extends Donation {
    }
    
    @Entity
    @DiscriminatorValue(DonationType.Exam)
    public class Exam extends Donation {
    }
    
    @Entity
    @DiscriminatorValue(DonationType.APPOINTMENT)
    public class Appointment extends Donation {
    }
    
    @Entity
    public class Voucher {
       //could be single mapping just to supperclass, depends on logic what do you need
       @ManyToOne
       private Adoption adoption;
    
       @ManyToOne
       private Exam exam;
    
       @ManyToOne
       private Appointment exam;
    
    }