JPA @ManyToMany连接表索引

时间:2011-12-06 20:34:21

标签: sql database hibernate optimization jpa

Hibernate允许通过使用@ManyToOne@org.hibernate.annotations.Index映射上添加索引。

有没有办法在@ManyToMany关系中指定连接表的索引?

如果实体A和实体B的{​​{1}} @ManyToMany是拥有方,则连接表将具有复合索引(a1,b1)。

我想知道这是否足够,还是我需要创建另一个索引(b1,a1)?

4 个答案:

答案 0 :(得分:4)

我也在寻找这个 - 看起来是圣杯。

在这篇文章中: How can I ask Hibernate to create an index on a foreign key (JoinColumn)?回答者似乎认为将@Index添加到集合会在连接表上创建索引。它没有。

这篇文章: How do I create an index on join tables using Hibernate annotations?揭示了我慢慢相信的可怕真相。除非您恢复使用hbm.xml文件来定义实体(即:使用注释似乎不可能),否则这是不可能的。

虽然它确实极大地加速了查询,在连接表上有一个复合索引,包含两个FK列,但目前无法使用注释自动创建所述索引。

我现在正在研究创建一个在Hibernate的ExportSchema执行之后用来识别连接表和创建索引的任务。它不是很好!请分享您遇到的任何可行的解决方案。我希望有人会分享他们的比较方法。

答案 1 :(得分:3)

在这里回答一个6岁的问题,但仍然具有相关性。我在面对同样的问题时遇到了这个问题。搜索Web使得JPA看起来不支持连接表上的索引,但确实如此,这是documented here

使用@JoinTable时,您可以在注释上指定索引,例如

@ManyToMany()
@JoinTable(name = "car_driver",
    joinColumns = @JoinColumn(name = "car_id"),
    inverseJoinColumns = @JoinColumn(name = "driver_id"),
    indexes = {
        @Index(name = "idx_car_driver_car_id", columnList = "car_id"),
        @Index(name = "idx_car_driver_driver_id", columnList = "driver_id")
    }
)
private Set<Driver> drivers;

答案 2 :(得分:1)

我在寻找一种如何控制连接表的方式时遇到了这个https://www.baeldung.com/jpa-many-to-many,因此我可以为其索引中的至少一个键编制索引。

它在联接表侧将多对多关系分解为多对一关系,并在两个关联实体的每一个上将典型的OneToMany分解为关联关系,如下所示:

@Entity
class Student {

    @OneToMany(mappedBy = "student")
    Set<CourseRating> ratings;
}

@Entity
class Course {

    @OneToMany(mappedBy = "course")
    Set<CourseRating> ratings;
}

@Entity
class CourseRating {

    @ManyToOne
    @MapsId("student_id")
    @JoinColumn(name = "student_id")
    Student student;

    @ManyToOne
    @MapsId("course_id")
    @JoinColumn(name = "course_id")
    Course course;       
}

@Index批注可用于CourseRating(联接表)实体中的任何字段。在我的情况下,由于在连接实体上读取表,因此在连接实体上使用了组合键,因此我实际上需要拆分关系。

我希望这会有所帮助。

答案 3 :(得分:0)

我想到了,我找到了解决方案。如果有多对多的关系我用过

@ManyToMany
@JoinTable(name = "core_auth_role", joinColumns = { @JoinColumn(name = "auth_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") }, uniqueConstraints = { @UniqueConstraint(columnNames = {
        "role_id", "auth_id" }) })
@ForeignKey(name = "fk_testkey", inverseName = "fk_testkey_inverse")
private Set<Role> roles;

结果我有两个idex(auth_id,role_id)和(role_id,auth_id)。 由Hibernate创建的模式:

create table SOME_TABLE ( 
    ...
    primary key (auth_id, role_id),
    unique (role_id, auth_id)
);

主键和唯一的cosntrainst会自动在数据库中编制索引。