繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM