Reputation: 1318
so I have following hierarchy of entities:
@MappedSuperClass
public abstract class BaseEntity {
private Long id;
private Date createAt;
private Date updateAt;
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
public abstract class Post extends BaseEntity {
private String creatorId;
private String title;
private String content;
}
@Entity
public class Article extends Post {
private String category; // article has category
}
@Entity
public class Journal extends Post {
private Date expiration; // journal has expiration
}
now when I use Spring Jpa Specification to query for articles with certain category, it won't work:
// define specification
public class ArticleSpecifications {
public static Specification<Article> withCategory(String category) {
(root, query, criteriaBuilder) ->
criteriaBuilder.equal(root.get("category"), category)
}
}
// repository
public interface PostRepository<T extends Post> extends JpaRepository<T, Long>, JpaSpecificationExecutor<T> { ... }
// usage: in some service class
@Autowired
private PostRepository<Article> articleRepository;
...
public void someMethod {
...
// error here
articleRepository.findAll(ArticleSpecifications.withCategory("news"), pageable);
...
}
Error message:
java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [category] on this ManagedType [com.gladdev.galahad.base.BaseEntity]
Just trying to understand here why it tries to look up "category" in BaseEntity.
Every Specification accessing attributes defined in Post works just fine.
Is it some spring jpa specification bug or I missed something?
Upvotes: 3
Views: 1735
Reputation: 3965
You can use the CriteriaBuilder.treat()
method.
In Criteria API, downcasting an entity to a subclass entity can be performed by using one of the
CriteriaBuilder.treat()
methods:
public static Specification<Article> withCategory(String category) {
return (root, query, criteriaBuilder) -> {
Root<Article> article = criteriaBuilder.treat(root, Article.class);
return criteriaBuilder.equal(article.get("category"), category);
};
}
Upvotes: 1