如何在Hibernate中为连接表添加单独的主键

时间:2010-09-21 16:24:31

标签: java hibernate orm jpa

我对Hibernate ManyToMany映射有疑问。我有两个类A和B,它们之间的映射是由Hibernate解决的ManyToMany映射:

@Entity
@Table(name="A")
public class A {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToMany
    @JoinTable(name="C", joinColumns=@JoinColumn(name="a_id"), inverseJoinColumns=@JoinColumn(name="b_id"))
    private Set bs;
}

@Entity
@Table(name="B")
public class B {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToMany(mappedBy="bs")
    private Set bs;
}

如您所见,我使用的连接表是C.A和B的外键是“a_id”和“b_id”。我的理解是,Hibernate为表C创建了一个带有a_id和b_id的组合主键。

我不希望在我的模型中有实体C.但是,我希望在字段a_id和b_id上有一个生成的ID和唯一约束,而不是表C上的组合主键。

是否可以告诉Hibernate使用单独的主键?没有添加实体C?

我将不胜感激。

非常感谢!

3 个答案:

答案 0 :(得分:6)

你应该这样做。但它只能用于列表(不适用于集合)

@Entity
@TableGenerator(name="ids_generator", table="IDS")
public class Passport {
    ...

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="PASSPORT_VISASTAMP")
    @CollectionId(
        columns = @Column(name="COLLECTION_ID"), 
        type=@Type(type="long"), 
        generator = "ids_generator"
    )
    private Collection<Stamp> visaStamp = new ArrayList();
    ...
}

答案 1 :(得分:1)

我认为不可能。我没有看到定义C实体的问题。

如果您在加入表中有任何其他信息,则无法访问该信息,因为您的Set包含目标实体 - AB

此外,您的Set会更好地利用泛型 - 即Set<A>Set<B>

顺便说一句,Hibernate可能不会因为表创建另一个实体而感到震惊 - 使用您当前的映射可能会起作用(完全忽略id列)。当你说“Hibernate创建”时,我假设你是从你的实体模型生成你的模式。现在看来情况正好相反,所以试一试。

答案 2 :(得分:1)

  

但是,我希望在字段a_id和b_id上有一个生成的ID和唯一约束,而不是表C上的组合主键。

通常,JoinTable的主键由两个外键组合而成。至少,这是JPA会产生的。但是如果你不使用JPA提供程序来生成模型,并且如果PK可以由数据库生成(使用IDENTITY列,触发器等),那么你应该能够使用{{ 1}} C关联的表(无需引入额外的实体并在两个ManyToMany中转换关系)。你真的试过吗?