JPA不返回EmbeddedId中包含空列的记录

时间:2016-02-21 07:11:24

标签: spring jpa spring-data-jpa

如果复合键中的任何字段为空,则JpaRepository' findAll()方法不会返回行。

这是具有 EmbeddedId JobVaccinationPK

的实体类
/**
 * ApplicationParam entity. @author MyEclipse Persistence Tools
 */
@Entity
@Table(name="job_vaccination",schema="cdcis")
@SuppressWarnings("serial")
public class JobVaccination  implements java.io.Serializable {


    // Fields    
     @Column(name="default_yn", length=1)
     private String defaultYn;

     @EmbeddedId
     private JobVaccinationPK jobVaccinationPK;

     public JobVaccination(){

     }

     //setters getters
}

这是嵌入式课程

@Embeddable
@SuppressWarnings("serial")
public class JobVaccinationPK implements Serializable{

    @ManyToOne
    @MapsId("job_category_id")
    @JoinColumn(name = "job_category_id", nullable=true)
    private JobCategoryTypeMast jobCategoryMast;

    @ManyToOne
    @MapsId("vaccination_id")
    @JoinColumn(name = "vaccination_id",   nullable=true)
    private VaccinationMast vaccinationMast;


    @ManyToOne
    @MapsId("screening_type_id")
    @JoinColumn(name = "screening_type_id",  nullable=true)
    private ScreeningTypeMast screeningTypeMast;

    //getters and setters
}

服务实施类

@Override
    public SearchResult<JobVaccinationDto> getJobVaccination(JobVaccinationDto dto)
            throws VaccinationException {

        List<JobVaccination> vaccDetails = jobVaccinationRepo.findAll();
        if(vaccDetails == null) return null;
        List<JobVaccinationDto> jobVaccinationDtos = new ArrayList<JobVaccinationDto>();
        jobVaccinationDtos = convertToDto(vaccDetails);
        return new SearchResult<>(jobVaccinationDtos.size(), jobVaccinationDtos);

}

此处可以为jobCategoryIdscreeningTypeId插入空值,就像下面的行一样。但是当我尝试获取具有空值的行时,它返回null。我试图调试,但我无法找到原因。

enter image description here

这是生成的hibernate查询:

 Hibernate: 
        select
            jobvaccina0_.job_category_id as job_cate4_13_,
            jobvaccina0_.screening_type_id as screenin2_13_,
            jobvaccina0_.vaccination_id as vaccinat3_13_,
            jobvaccina0_.default_yn as default_1_13_ 
        from
            cdcis.job_vaccination jobvaccina0_
    Hibernate: 
        select
            jobcategor0_.job_category_id as job_cate1_11_0_,
            jobcategor0_.job_category_name as job_cate2_11_0_,
            jobcategor0_.job_category_name_ar as job_cate3_11_0_,
            jobcategor0_.screening_type_id as screenin4_11_0_ 
        from
            cdcis.job_category_mast jobcategor0_ 
        where
            jobcategor0_.job_category_id=?
    Hibernate: 
        select
            screeningt0_.screening_type_id as screenin1_21_0_,
            screeningt0_.active_yn as active_y2_21_0_,
            screeningt0_.mmpid_required_yn as mmpid_re3_21_0_,
            screeningt0_.screening_type as screenin4_21_0_ 
        from
            cdcis.screening_type_mast screeningt0_ 
        where
            screeningt0_.screening_type_id=?
    Hibernate: 
        select
            vaccinatio0_.vaccination_id as vaccinat1_27_0_,
            vaccinatio0_.vaccination_name as vaccinat2_27_0_,
            vaccinatio0_.vaccination_name_ar as vaccinat3_27_0_ 
        from
            cdcis.vaccination_mast vaccinatio0_ 
        where
            vaccinatio0_.vaccination_id=?

与@Adam Michalik一起回答。作为一种解决方法,我在表中引入了一个新的主键字段,因为我们无法在复合键中处理null。

enter image description here

2 个答案:

答案 0 :(得分:3)

复合ID在任何字段中都不能包含空值。由于NULL的SQL语义是NULL <> NULL,因此无法确定主键(1, 2, NULL)是否等于(1, 2, NULL)

NULL在SQL中意味着“没有价值”,它的解释取决于具体情况。这就是为什么SQL和JPA不想假设NULL = NULL并且包含NULL的主键仅标识单个实体。

您可以选择使用合成的生成主键而不是复合业务主键来克服这一点。然后,你总是有一个非空的单列PK和可以为空的外键。

答案 1 :(得分:-1)

将实体中特定行的数据类型从int更改为整数