我有两张表,它们之间有
FK
关系。父表在两列上有一个composite primary key
,其中一列用于链接子表。
有趣的是,当我尝试获取使用显式
INNER JOIN
链接孩子的父母列表时,我收到了重复项。重复计数暗示子表有问题,因为所有结果的最终计数等于{relevant parent records count} × {count of all even unrelated child records}
.
父实体:
class CropDiseasePK implements Serializable {
private UUID cropId;
private UUID diseaseId;
}
@Entity
@Converter(name="uuidConverter", converterClass=UUIDEclipseConverter.class)
@IdClass(CropDiseasePK.class)
@Table(name="crop_disease")
public class CropDisease {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "disease_id")
private Disease disease;
@JsonIgnore
@Id
@Column(name = "disease_id", insertable = false, updatable = false)
@Convert("uuidConverter")
private UUID diseaseId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "crop_id")
private Crop crop;
@JsonIgnore
@Id
@Column(name = "crop_id", insertable = false, updatable = false)
@Convert("uuidConverter")
private UUID cropId;
... more unrelated columns ...
子实体(相当标准的情况):
@Entity
@Converter(name="uuidConverter", converterClass=UUIDEclipseConverter.class)
@Table(name="disease")
public class Disease {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Convert("uuidConverter")
@Column(nullable = false)
private UUID id;
... more unrelated columns ...
在 DAO 类中,我获取父记录列表
@Stateless
public class DiseaseDAO {
@Inject
private EntityManager em;
... more unrelated DAO methods ...
public List<CropDisease> getCropDiseases(Crop crop) {
return em.createQuery(
"SELECT c " +
"FROM CropDisease c " +
"INNER JOIN Disease d " +
"WHERE c.crop = :crop " +
"ORDER BY d.order",
CropDisease.class)
.setParameter("crop", crop)
.getResultList();
}
}
有趣的是,一旦我注释掉明确的
INNER JOIN
,结果就可以了,但是我不能ORDER BY
子实体的列。
似乎问题出在 JPA 端的某种记录的最终组装中,因为在这两种情况下针对 RDBMS 发出的 SQL 查询是相同的,除了查询排序。
(我不包括纯文本日志,因为我觉得它没有用——但当然有可能。)
我是否遗漏了一些实体注释或配置 WRT 组合键?可以肯定的是-如果两个实体都有单列,则相同的机制可以正常工作
PK
.
哦,没关系,这是一个错字——查询应该是这样的:
public List<CropDisease> getCropDiseases(Crop crop) {
return em.createQuery(
"SELECT c " +
"FROM CropDisease c " +
"INNER JOIN c.disease d " + // <== alias.propertyName here
"WHERE c.crop = :crop " +
"ORDER BY d.order",
CropDisease.class)
.setParameter("crop", crop)
.getResultList();
}
我会预料到像这样的错字会出错。