如何在Hibernate中向联接表添加单独的主键

10

我对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将使用a_id和b_id创建组合主键用于表C。

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

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

非常感谢您的任何帮助。

非常感谢!

3个回答

8
你应该这样做。但它只适用于列表(而不是集合)。
@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

我认为这是不可能的。而且,定义一个C实体也没有问题。

如果在联接表中有任何其他信息,它将无法访问,因为您的Set包含目标实体-AB

此外,您的Set最好使用泛型-i.e. Set<A>Set<B>

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


重点是数据库已经存在,并且具有给定的结构(由于遗留原因,它实际上不太适应)。该表中除了我提到的三个字段(id、a_id、b_id)之外没有其他内容。在不创建代码中的(无用的)C实体的情况下插入新条目将是很好的。但还是谢谢你的回答。我想我只能创建这个实体了... - BHulliger
@Bozho 我是否可以使用 Embeddable 注解来创建一个单独的实体? - Asma Rahim Ali Jafri

1
但是,我希望在表C上有一个生成的ID和对字段a_id和b_id的唯一约束,而不是一个组合的主键。
通常,JoinTable的主键由两个外键的组合组成。至少,这就是JPA将生成的内容。但是,如果您不使用JPA提供程序生成模型,并且如果可以通过数据库生成PK(使用IDENTITY列、触发器等),那么您应该能够使用C表来进行ManyToMany关联(而无需引入额外的实体并将关系转换为两个OneToMany)。您真的尝试过吗?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接