Java 抽象类上的Hibernate/JPA映射

Java 抽象类上的Hibernate/JPA映射,java,mysql,hibernate,jpa,Java,Mysql,Hibernate,Jpa,使用Hibernate实现以下情况的最佳实践是什么 我们定义了一个抽象类,它将构成我们希望在数据库中持久化的任何对象的基础。它包含id等 public abstract class ModelObject { protected int id; ... } 现在,我们为特殊情况下的基类划分子类,其中多个实体将具有类似的字段 public abstract class ModelObjectWithNose extends ModelObject { ... p

使用Hibernate实现以下情况的最佳实践是什么

我们定义了一个抽象类,它将构成我们希望在数据库中持久化的任何对象的基础。它包含id等

public abstract class ModelObject {
    protected int id;

    ...
}
现在,我们为特殊情况下的基类划分子类,其中多个实体将具有类似的字段

public abstract class ModelObjectWithNose extends ModelObject {
    ...
    protected Nose nose;
}
现在,对于我们想要有一个
鼻子的所有类:

public class Person extends ModelObjectWithNose { ... }

public class Animal extends ModelObjectWithNose { ... }
我们现在面临的真正问题是,这种关系需要是双向的。每个具体类都需要知道哪个
Nose
是他们的,但是每个
Nose
也需要知道它属于哪个对象

public class Nose {
    ...
    private ModelObjectWithNose owner;
}
对于我们的示例,我们需要一个
@OneToOne
关系,因为每个
只能有一个
鼻子
,每个
鼻子
只能属于一个

我们尝试的是执行以下操作:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class ModelObjectWithNose extend ModelObject { ... }
然后:

@Entity
public class Person extends ModelObjectWithNose { ... }
……等等等等

1) 如何定义
Nose
ModelObjectWithNose
之间的关系?它是否简单到:

@Entity
public class Nose {
    ...
    // this causes: 'Basic' attribute should not be 'Persistence Entity' 
    ModelObjectWithNose owner;
}
2) 有更好/更受欢迎的方法吗?继承策略能正常工作吗

谢谢

编辑


因此,我尝试了几种可能有效的方法。如果您像问题中那样设置注释,那么使用三种继承方案中的任何一种都可以很好地工作。不幸的是,这对我们现有的数据库和代码有着巨大的影响,所以我们选择(现在)只需索引当前对象上保留的
Nose
对象的
id
字段,该字段将扩展
ModelObjectWithNose
,并只需编写助手方法进行点查询以查找条目。

ModelObjectWithNose
中将
Nose
属性注释为
@OneToOne
,并在您对
ModelObjectWithNose-owner
执行相同操作的
Nose
实体。设置
Nose
实体注释的
mappedBy
属性,以便JPA知道应该在哪个表上插入FK(在您的模型中,
ModelObjectWithNose
应该具有FK to
Nose
,而不是相反。您可以将其设置在一对一关系的反向端,即具有要使用的PK的一端。)

顺便说一句,您的实体必须实现
Serializable
(您可以在
ModelObject
类上执行此操作,以在继承类上强制执行)。
ModelObject
id
属性应注释为
@id

干杯,
Kai

映射中的
@OneToOne
s在哪里?@axtavt-因此@OneToOne将同时位于
Nose
类中的
ModelObjectWithNose
ModelObjectWithNose
类中的
Nose
上。有关详细信息,请参阅我的编辑。您想详细说明“巨大影响”吗您的代码中有各种继承策略?读起来会很有趣。@Tom Anderson-好吧,因为我们的代码库已经相当成熟(+-3年),并且最初的设计没有考虑到这种继承,朝着这一方向迈进将意味着重写大多数
@Entity
类(其中有100多个)。此外,我们不能简单地重新创建数据库,因为许多客户都在使用它。因此,我们必须要么编写SQL到
更改现有数据库,以模拟其外观,要么编写ETL过程来进行转换。谢谢。上面的代码只是框架代码。我们的
ModelObject
确实实现了
系列alizable
。我还添加了
@OneToOne
。正如我在一篇评论中提到的,我们选择了不同的解决方案,因为我们必须对现有代码进行太多更改。但是,谢谢,您的解决方案会起作用(我在一个小的概念验证上进行了尝试)。