我发现了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);