ORM - MappedSuperclass上的ManyToMany关系

时间:2012-01-29 17:35:26

标签: java hibernate orm

我有一个课程如下:

AnimalClass [Id, Name, Set<Tag>]
|
+-- FishClass [FishSpecific]
+-- MammalClass [MammalSpecific]

Tag [Name]

因此,任何动物都可以拥有任意数量的相关标签。

为此我在AnimalClass中使用:

@JoinTable(name="Animal_Tag")
@JoinColumn(name="animal_id", referencedColumnName="id", nullable=false)
@OneToMany(cascade=CascadeType.ALL)
@Getter
protected Set<Tag> tags = new HashSet<Tag>();

我的问题是,Hibernate将m-n表创建为:

 Animal_Tag [FishClass_id, MammalClass_id, Tag_id]. 

我更愿意使用某种枚举:

 Animal_Tag [Animal_id, AnimalTypeEnumeration[ Fish | Mammal ], Tag_id].

谢谢!

3 个答案:

答案 0 :(得分:2)

我怀疑你不能用映射的超类做到这一点。

关于映射超类的事情是它没有定义持久类型。它为持久化类型定义了一种模板。每次定义注释@Entity的子类时,都会创建模板的实例,但在数据模型中,这些类型之间没有关系。使用映射的超类几乎是将给定字段集复制并粘贴到新实体类中的快捷方式。

因此,就数据模型而言,没有可能的animal_id,因为没有动物类型。数据库中只存在鱼类和哺乳动物。

你能使AnimalClass成为一个实体而不是映射的超类吗?如果使用每类表继承策略,则不需要为其创建表。但它会使动物成为一种类型,这意味着ORM将能够使用animal_id。

答案 1 :(得分:2)

您想要的表结构将具有可以指向不同表的外键,具体取决于另一个字段的值。我认为任何数据库都不允许这样做。

与ORM的多态性总是很棘手。最好的办法就是尽可能避免它。否则,也许你可以在Animal上使用@Inheritance(strategy=InheritanceType.JOINED)?这将导致像这样的表结构:

TABLE Animal
 - id (primary key)

TABLE Fish
 - id (foreign key -> Animal)
 - fins
 - scales

TABLE Mammal
 - id (foreign key -> Animal)
 - mammaries 

答案 2 :(得分:1)

可以使用AnimalClass的“每子类的表和判别器”继承吗?在休眠的情况下,它会导致雇佣人员:

AnimalClass [Id, AnimalTypeEnumeration (discriminator), Name]
|
+-- FishClass [FishSpecific]
+-- MammalClass [MammalSpecific]
Animal_Tag [Animal_id, Tag_id]