hibernatejpaspring-data-jpajpa-2.0jpa-2.1

Spring JPA DTO projection and handling the nested projection with null values


I am using class based projection with constructor expressions. here is a sample code form my work

@Query("select new com.core.data.category.CategoryDto(c.id,c.code,c.externalCode,c.seoMeta, c.createdAt, c.updatedAt,c.parent.code) FROM Category c where c.code = :code")
CategoryDto findCategoryByCode(@Param("code") String code); 

This is how my CategoryDto look like:

public class CategoryDto implements Serializable {
 
private Long id;
private String code;
private String externalCode;
private SEOMeta seoMeta;
private CategoryDto parent;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
Map<String, LocCategoryDto> translation;

//constructor based on the requirement
}

This seems to be working fine except in one case where the property for the nested object is null. in my case the parent property can be null in case this is a root category but it seems using c.parent.code causing the issue and the entire object is coming null. Can someone help me with the following queries

  1. Is there a way to handle this case using the same constructor expressions? I tried to look in to the doc but did not find the details.
  2. I think other option might be using ResultTransformer (which will bind my code to specific JPA)but I did not find any information as how I can use it with Spring JPA.

Update I even tried the option to use the CASE option but seems this is also not working for me as I am still getting the null entity (while data is available in the DB). Here is the updated code I tried

@Query(value = "select new com.core.data.category.CategoryDto(c.id,c.code,c.externalCode,c.seoMeta, c.createdAt, c.updatedAt, " +
            "CASE " +
            "WHEN  c.parent is NULL " +
            "THEN NULL " +
            "ELSE c.parent.code " +
            "END ) " +
            "FROM Category c where c.code = :code")
    CategoryDto findCategoryByCode(@Param("code") String code);

Edit 2 I had also tried even with join but that also seems not working for.

Update: I did a silly mistake.Was using the simple join and not left join which caused this issue.


Solution

  • try using left join

    @Query("select new com.core.data.category.CategoryDto(c.id,c.code,c.externalCode,c.seoMeta, c.createdAt, c.updatedAt,parent.code) FROM Category c left join c.parent as parent where c.code = :code")
    CategoryDto findCategoryByCode(@Param("code") String code);