Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring-Data Pageable sort on JPA discriminator field

I've got a JPA entity hierarchy with JPA joined inheritance:

@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING)
Product

and

@Entity
@Table(name = "product_quiz")
@DiscriminatorValue("quiz")
public class QuizProduct extends Product

I want to run a spring-data query with QueryByExample and PageRequest like this:

Example<Product> example = ...
PageRequest pageRequest = ...
Page<Product> productPage = productRepository.findAll(example, pageRequest);

It works fine, except if I set sortField of the pageRequest to be "type" (the @DiscriminatorColumn).

I've tried to:

  • directly add the type field to the entity. This way the query runs fine, but the persisting operation fails with org.postgresql.util.PSQLException: The column index is out of range: 11, number of columns: 10.
  • if I mark this field as @Transient, the persisting works, but the query gives me this exception: Unable to locate Attribute with the the given name [type] on this ManagedType [...AbstractEntityWithDate] (AbstractEntityWithDate is a @MappedSuperclass of Product, which contains creationDate and modificationDate)

I'm using spring-boot version 1.4.5.RELEASE with the dependency-managed versions of spring-data-jpa(1.10.8.RELEASE) and hibernate(5.0.12.Final).

How can I configure the sorting by discriminator field with Pageable? (I don't want to write custom @Query for this).

like image 613
C-Shark Avatar asked May 15 '17 08:05

C-Shark


1 Answers

Discriminator columns can be mapped as read-only entity attributes

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "TYPE", discriminatorType = DiscriminatorType.STRING)
class Product {
  @Column(name = "TYPE", insertable = false, updatable = false)
  private String type;
}

Then, the following query will work:

productRepository.findAll(new Sort("type"))

Working sample available on Github.


Having said this, attempting to use the discriminator value in code with inheritance strategy JOINED will not work with Hibernate (type will always be null). This is because traditionally Hibernate has not supported @DiscriminatorColumn with JOINED (see HHH-6911) and has only started to save the column value for joined inheritance with v4.2.9 onwards. It seems like there is still a bug that does not read the discriminator column value, even though the value is saved correctly.

like image 88
manish Avatar answered Sep 24 '22 18:09

manish