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

JPA not returning the records which contain empty columns in the EmbeddedId

JpaRepository 的 findAll() 方法不 return 行,如果复合键中的任何字段为空。

这是具有 EmbeddedId JobVaccinationPK

的实体 class
/**
 * 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
}

这是内嵌的class

@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
}

服务实施class

@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 插入一个空值,就像下面的行一样。但是当我试图获取具有空值的行时,它 return 为空。我试过调试,但找不到原因。

这是生成的休眠查询:

 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 一起回答。作为解决方法,我在 table 中引入了一个新的主键字段,因为我们无法处理复合键中的空值。

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

NULL 表示 SQL 中的 "no value",其解释取决于您的具体情况。这就是为什么 SQL 和 JPA 不想假设 NULL = NULL 并且包含 NULL 的主键仅标识单个实体。

您可以选择使用合成的、生成的主键而不是复合业务主键来克服这个问题。然后,您将始终拥有一个非空的单列 PK 和可为空的外键。

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