Java 抽象类上的Hibernate/JPA映射
使用Hibernate实现以下情况的最佳实践是什么 我们定义了一个抽象类,它将构成我们希望在数据库中持久化的任何对象的基础。它包含id等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
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 toNose
,而不是相反。您可以将其设置在一对一关系的反向端,即具有要使用的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
。正如我在一篇评论中提到的,我们选择了不同的解决方案,因为我们必须对现有代码进行太多更改。但是,谢谢,您的解决方案会起作用(我在一个小的概念验证上进行了尝试)。