为什么@JoinColumns的顺序很重要?

时间:2018-10-10 19:39:35

标签: java hibernate jpa spring-data-jpa

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

0 个答案:

没有答案