Java 如何使用继承处理JPA CollectionTable?

Java 如何使用继承处理JPA CollectionTable?,java,hibernate,jpa,Java,Hibernate,Jpa,我必须创建一个类的层次结构,其中超类有一个表示映射的@CollectionTable。我试图实现它,但它只适用于一个子类 我想做以下几件事。左边是当前结构,右边是所需结构。 稳定(工作)代码如下所示: @MappedSuperclass public class Animal { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false,

我必须创建一个类的层次结构,其中超类有一个表示映射的
@CollectionTable
。我试图实现它,但它只适用于一个子类

我想做以下几件事。左边是当前结构,右边是所需结构。

稳定(工作)代码如下所示:

@MappedSuperclass
public class Animal {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;
}

@Entity(name = "cats")
@Audited
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue(value = Cat.PET_TYPE)
public abstract class Cat extends Animal {
    public static final String PET_TYPE = "C";

    @ElementCollection(fetch = FetchType.EAGER)
    @MapKeyColumn(name = "name")
    @Column(name = "value")
    @CollectionTable(name = "cat_properties", joinColumns = @JoinColumn(name = "cat_id"))
    private Map<String, String> properties = new HashMap<>();
}

@Audited
@Entity(name = "persiancats")
@DiscriminatorValue(value = PersianCat.PERSIAN_CAT_TYPE)
public class PersianCat extends Cat {
    public static final String PERSIAN_CAT_TYPE = "P";
}
@MappedSuperclass
公营动物{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”,updateable=false,nullable=false)
私人长id;
}
@实体(名称=“猫”)
@审计
@继承(策略=InheritanceType.SINGLE_表)
@鉴别器列(name=“type”,discriminatorType=discriminatorType.CHAR)
@鉴别器值(值=类别PET_类型)
公共抽象类Cat扩展了Animal{
公共静态最终字符串PET_TYPE=“C”;
@ElementCollection(fetch=FetchType.EAGER)
@MapKeyColumn(name=“name”)
@列(name=“value”)
@CollectionTable(name=“cat\u properties”,joinColumns=@JoinColumn(name=“cat\u id”))
私有映射属性=新HashMap();
}
@审计
@实体(名称=“波斯”)
@鉴别器值(值=波斯猫、波斯猫类型)
公共类波斯猫{
公共静态最终字符串\u CAT\u TYPE=“P”;
}
这就是我试图实现修改的方式:

@MappedSuperclass
public class Animal {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;
}

@MappedSuperclass
public abstract class Pet extends Animal {
    @ElementCollection(fetch = FetchType.EAGER)
    @MapKeyColumn(name = "name")
    @Column(name = "value")
    @CollectionTable(name = "pet_properties", joinColumns = @JoinColumn(name = "pet_id"))
    private Map<String, String> properties = new HashMap<>();
}

@Entity(name = "cats")
@Audited
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue(value = Cat.PET_TYPE)
public class Cat extends Pet {
    public static final String PET_TYPE = "C";
}

@Entity(name = "dogs")
@Audited
public class Dog extends Pet {
}

@Audited
@Entity(name = "persiancats")
@DiscriminatorValue(value = PersianCat.PERSIAN_CAT_TYPE)
public class PersianCat extends Pet {
    public static final String PERSIAN_CAT_TYPE = "P";
}
@MappedSuperclass
公营动物{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
@列(name=“id”,updateable=false,nullable=false)
私人长id;
}
@映射超类
公共抽象类宠物动物{
@ElementCollection(fetch=FetchType.EAGER)
@MapKeyColumn(name=“name”)
@列(name=“value”)
@CollectionTable(name=“pet\u properties”,joinColumns=@JoinColumn(name=“pet\u id”))
私有映射属性=新HashMap();
}
@实体(名称=“猫”)
@审计
@继承(策略=InheritanceType.SINGLE_表)
@鉴别器列(name=“type”,discriminatorType=discriminatorType.CHAR)
@鉴别器值(值=类别PET_类型)
公营宠物猫{
公共静态最终字符串PET_TYPE=“C”;
}
@实体(名称=“狗”)
@审计
公家级宠物狗{
}
@审计
@实体(名称=“波斯”)
@鉴别器值(值=波斯猫、波斯猫类型)
公共级波斯猫{
公共静态最终字符串\u CAT\u TYPE=“P”;
}
Hibernate创建宠物属性表,但它只引用狗或猫。我的意图是为狗和猫(以及波斯猫)的财产创建一个公共表


我遗漏了什么或做错了什么?

在我删除了这个
@CollectionTable(name=“cat\u properties”,joinColumns=@JoinColumn(name=“cat\u id”)
行之后,Hibernate创建了两个表,一个称为cats\u properties(用于猫和波斯猫),另一个称为dogs\u properties。这并不完全是我想要的,这是两个实体的一个通用表,但它是可以接受的。

我猜您试图实现的逻辑上是不可能的,原因如下(我偶然发现了相同的问题,尽管是在另一个领域)。要从
pet_属性
表中引用表,Hibernate将从
pet_属性
创建一个外键到目标表(在您的情况下是狗或猫)。外键本质上意味着这个表中的每个条目都应该对应另一个表中的条目,而另一个表只是一个表。因此,如果您说您的
pet_属性
条目同时引用
dogs
cats
表,那么它将立即中断外键属性,因为如果它引用dogs,那么它就不会引用cats,反之亦然


因此,Hibernate提供的自动生成选项(单独的表
dogs\u properties
cats\u properties
)似乎是正确的方法。

几乎相同的问题。。你找到另一个解决办法了吗?我无法创建更多的表,因为它们可能是10个