Set the discriminator value for hibernation to use the bind variable instead of literal

When using @DiscriminatorColumn for a class and @DiscriminatorValue in the SQL subclasses that Hibernate generates, it uses the discriminator value as a literal for the sentence involving the discriminator column.

Example:

@Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "PART_TYPE") @Table(name = "NAME") public class NamePartEntity implements Comparable<NamePartEntity> { // Stuff } @Entity @DiscriminatorValue(value = "GIV") public class GivenNameEntity extends NamePartEntity { // stuff } 

If I create a simple query of criteria without any criteria other than a class, I would get SQL-generated in this way:

 select this_.person_id as y0_ from name this_ where this_.part_type='GIV' 

This is not so bad until you get multiple discriminator values, and the table can be selected from several times, so the query looks like this:

 SELECT this_.person_id AS y0_ FROM name this_ WHERE this_.part_type='FAM' AND this_.value_u =:8 AND this_.tenant_id =:9 AND this_.person_id IN (SELECT this_.person_id AS y0_ FROM name this_ WHERE this_.part_type='GIV' AND this_.value_u =:10 AND this_.tenant_id =:11 AND this_.person_id IN (SELECT this_.person_id AS y0_ FROM name this_ WHERE this_.part_type='GIV' AND this_.value_u =:12 AND this_.tenant_id =:13 AND this_.person_id IN (SELECT this_.person_id AS y0_ FROM name this_ WHERE this_.part_type='PFX' AND this_.value_u =:14 AND this_.tenant_id =:15 ) ) ) 

can have a ton of different SQL identifiers and literal-based execution plans ("FAM", "GIV", "PFX" in this case, but they can be different and in different orders). However, if binding variables were used instead of these discriminator values, this would be the same sql identifier and would have the same execution plan.

So, is it possible that Hibernate uses column annotations / discriminator values ​​in such a way that connected variables are used instead of variables? I know that I could rewrite my entities in such a way as to avoid this, but I wanted to see if I could somehow get the functionality of the variable binding with existing annotations.

As an alternative, can I use my extended classes without using discriminator values? If I try this and you have an @Entity annotation for each extended class, it complains about the absence of a discriminator type, even if there are no discriminator annotations.

+5
source share
2 answers

No, this cannot be done out of the box.

The closest workaround that comes to my mind is to select from the base class and explicitly filter the subclass:

 entityManager.createQuery("select gne from NamePartEntity gne where type(gne) = :subclass") .setParameter("subclass", GivenNameEntity.class) .getResultList(); 
+1
source

Alternatively, is there a way I can use extended classes without using discriminator values? If I try, and I have @Entity annotations for each extended class, it complains about the lack of discriminator, even if there are no discriminator annotations

This is because of the InheritanceType.SINGLE_TABLE strategy you used. You can always try using other strategies, such as InheritanceType.JOINED , depending on what you request most often.

In another note: Does this many types of Names per-se have an indicator that should have types as a relation, and not a subtype?

0
source

Source: https://habr.com/ru/post/1273218/


All Articles