'Spring JPA InheritanceType.JOINED how to resolve record type

In my spring app I have a entity hierarchy like this:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
class A

@Entity
class B extends A

@Entity
class C extends A

@Entity
class D extends A

I want to have a jpa repository method that will update all records of type given by query param. I already created such method:

@Modifying    
@Query("UPDATE A AS a SET a.someAttr = 1 WHERE TYPE(a.class) = (:clazz)")  
void updateRecordsOfType(@Param("clazz") Class<? extends A> clazz)

But it doesn't work. It throws org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "A0_1_.ID" not found; Hibernate seems not to join tables B, C and D when generating query.

It worked fine, when I used @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) in A class.

Is there any way to resolve the record type when using @Inheritance(strategy = InheritanceType.JOIN)?

============ UPDATE ============
As I suspected this is probably a bug in Hibernate. I enabled sql logging and I found that query generated by Hibernate is not right. For comparison, this is a query generated by ARepository.findAll() method:

select
        a0_.id as id1_0_,
        a0_.some_attr as some_att2_0_,
        case 
            when a0_1_.id is not null then 1 
            when a0_2_.id is not null then 2 
            when a0_3_.id is not null then 3 
            when a0_.id is not null then 0 
        end as clazz_ 
    from
        a a0_ 
    left outer join
        b a0_1_ 
            on a0_.id=a0_1_.id 
    left outer join
        c a0_2_ 
            on a0_.id=a0_2_.id 
    left outer join
        d a0_3_ 
            on a0_.id=a0_3_.id

and this is a query generated by method updateRecordsOfType defined above:

update
    a 
set
    some_attr='someValue' 
where
    case 
        when a0_1_.id is not null then 1 
        when a0_2_.id is not null then 2 
        when a0_3_.id is not null then 3 
        when id is not null then 0 
    end=?

It seems to be only partially generated, because FROM and JOIN clauses, present in the first query, are missing. This is the reason org.h2.jdbc.JdbcSQLSyntaxErrorException: Column "A0_1_.ID" not found; is thrown. Method updateRecordsOfType is annotated with @Query() and it's value contains query with TYPE() function.

To sum up, everything works fine until I use TYPE() function. I couldn't resolve this issue. I gave up on InheritanceType.JOINED and I used InheritanceType.TABLE_PER_CLASS.



Solution 1:[1]

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "typeA")
class A

@Entity
@DiscriminatorValue("B")
class B extends A

@Entity
@DiscriminatorValue("C")
class C extends A

@Entity
@DiscriminatorValue("D")
class D extends A {}

I had the same problem using this inheritance , but couldn't find my way, temporoary i've change the inheritance type by using Inheritance(strategy = InheritanceType.SINGLE_TABLE) => but, all records will be saved on the same entity.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mirlo