[英]Why does the order of @JoinColumns matter?
我发现 Hibernate 有一些奇怪的行为。 我在使用这样的嵌入式复合主键的两个实体之间存在一对多关系。 (是的,我知道数据设计很糟糕,但这是我必须使用的架构)
@Entity
@Table(name = "T_PLACE")
public class Place {
@EmbeddedId
private PlacePK id;
@OneToMany(mappedBy = "place")
private List<Mode> modes;
// getters and setters
}
@Embeddable
public class PlacePK implements Serializable {
@Column(name = "COMPANY")
private String company;
@Column(name = "AREA")
private String area;
@Column(name = "COLOR")
private String color;
// getters and setters
}
@Entity
@Table(name = "T_MODE")
public class Mode {
@EmbeddedId
private ModePK id;
@ManyToOne
@JoinColumns({
@JoinColumn(name = "COMPANY", insertable = false, updatable = false),
@JoinColumn(name = "AREA", insertable = false, updatable = false),
@JoinColumn(name = "COLOR", insertable = false, updatable = false),
})
private Place place;
private String function;
// getters and setters
}
@Embeddable
public class ModePK implements Serializable {
@Column(name = "COMPANY")
private String company;
@Column(name = "AREA")
private String area;
@Column(name = "COLOR")
private String color;
@Column(name = "MODE_ID")
private String color;
// getters and setters
}
但是在查询一个地方的模式时,生成的 HQL 最终会像这样排序
where
company=?
and color=?
and area=?
它最终将区域绑定到第二个?
和颜色到第三?
.
除非我更改@JoinColumn
的顺序以将颜色放在区域之前,否则它不起作用。
@JoinColumns({
@JoinColumn(name = "COMPANY", insertable = false, updatable = false),
@JoinColumn(name = "COLOR", insertable = false, updatable = false),
@JoinColumn(name = "AREA", insertable = false, updatable = false),
})
所以我的问题是,是什么导致了这种行为? 什么决定了 HQL 中 where 子句的顺序? 这不是任何问题,因为我已经弄清楚如何使它工作,但我想了解它。
我正在使用spring-boot-starter-data-jpa:1.5.10-RELEASE
,它使用 Hibernate 5。
编辑
这是我制作 HQL 的方式
@Repository
public interface PlaceRepository extends JpaRepository<Place, PlacePK> {}
然后在测试中:
PlacePK placePK = new PlacePK();
placePK.setCompany("Acme");
placePK.setArea("XYZ");
place.PK.setColor("Blue");
Place place = placeRepository.findOne(placePK);
List<Mode> modes = place.getModes(); // ends up being an empty PersistBag until I switch the order of the @JoinColumns
assertNotNull(modes);
该命令是 matte,因为基于此命令 Hibernate 构建一个连接条件。 Hibernate 不知道如何将 map 特定列相互连接(尽管它可以通过命名比较来实现,但是......)。 因此,只需将它们按照您指定的顺序与 ID 列相同即可。
要查看排序的不同之处,请打开生成的 SQL 查询的日志记录。 您会看到,如果您的订单与 ID 键的顺序不一致,您的 fetch 查询可能会以类似的方式结束
...join PlacePK pk ON pk.COMPANY = m.AREA*emphasized text*
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.