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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3762361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:16:39  来源:igfitidea点击:

How to add a separate Primary Key to a Join Table in Hibernate

javahibernateormjpa

提问by BHulliger

I have a question about Hibernate ManyToMany mappings. I have two classes A and B and the mapping between them is a ManyToMany mapping resolved by Hibernate:

我有一个关于 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;
}

As you can see, the Join Table I use is C. The foreign keys to A and B are "a_id" and "b_id". My understanding is, that Hibernate creates a composed Primary Key with a_id and b_id for table C.

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

I don't want to have an entity C in my model. But instead of a composed primary key on table C, I would like to have a generated ID and a unique constraint on the fields a_id and b_id.

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

Is it possible to tell Hibernate to use a separate primary key? Without adding an entity C?

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

I would appreciate any help.

我将不胜感激任何帮助。

Thanks a lot!

非常感谢!

回答by Igor

You should do iyt like this. But it can be appled only for list (not for sets)

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

@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();
    ...
}

回答by Bozho

I don't think it is possible. And I don't see a problem in defining a Centity.

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

If you have any additional information ind the join-table, it will not be accessible to you, because your Setcontains the target entity - Aor B.

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

Also, your Sets would better make use of generics - i.e. Set<A>and Set<B>.

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

Btw, Hibernate might not be alarmed by the fact that the table creates another entity - using your current mapping might work (disregarding completely the id column). When you said "Hibernate creates", I assumed you are generating your schema from your entity model. Now it seems it's the opposite, so give it a try.

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

回答by Pascal Thivent

But instead of a composed primary key on table C, I would like to have a generated ID and a unique constraint on the fields a_id and b_id.

但是,我想要生成的 ID 和字段 a_id 和 b_id 上的唯一约束,而不是表 C 上的组合主键。

Normally the primary key of the JoinTableis made of the combination of both foreign keys. At least, this is what JPA would generate. But if you don't use the JPA provider to generate the model and if the PK can be generated by the database (using an IDENTITYcolumn, a trigger, etc), then you should be able to use the Ctable for your ManyToManyassociation (without having to introduce an extra entity and to transform the relation in two OneToMany). Did you actually try?

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