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);
}
这里可以为 jobCategoryId
或 screeningTypeId
插入一个空值,就像下面的行一样。但是当我试图获取具有空值的行时,它 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
JpaRepository 的 findAll()
方法不 return 行,如果复合键中的任何字段为空。
这是具有 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
}
这是内嵌的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);
}
这里可以为 jobCategoryId
或 screeningTypeId
插入一个空值,就像下面的行一样。但是当我试图获取具有空值的行时,它 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