使用Hibernate将子类持久化为超类

使用Hibernate将子类持久化为超类,hibernate,inheritance,Hibernate,Inheritance,我有一个子类和一个超类。但是,只需要保留超类的字段 session.saveOrUpdate((Superclass) subclass); 如果我执行上述操作,我将得到以下异常 org.hibernate.MappingException: Unknown entity: test.Superclass at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:628)

我有一个子类和一个超类。但是,只需要保留超类的字段

session.saveOrUpdate((Superclass) subclass);
如果我执行上述操作,我将得到以下异常

org.hibernate.MappingException: Unknown entity: test.Superclass
    at org.hibernate.impl.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:628)
    at org.hibernate.impl.SessionImpl.getEntityPersister(SessionImpl.java:1366)
    at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:203)
    at org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:535)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:103)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:535)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:527)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:523)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.hibernate.context.ThreadLocalSessionContext$TransactionProtectionWrapper.invoke(ThreadLocalSessionContext.java:342)
    at $Proxy54.saveOrUpdate(Unknown Source)

如何将子类持久化为超类?我不喜欢创建一个超类实例,然后从子类实例传递值。因为,如果将来向超类添加额外的字段,很容易忘记更新逻辑。

您试图实现的目标将给您带来很多问题。想象一下如果再次加载数据会发生什么。Hibernate应该使用哪个类?超类?还是其中的一个子类?哪一个


我建议直接映射超类,然后使用来实现扩展功能(基本上是将超类转换为数据对象,然后传递给“worker”实例)。

我还想找到一种方法来实现这一点。这是一个令人振奋的案例。假设我有一个用户对象来表示我的应用程序中的用户。用户对象有一些属性,如用户名、密码、电子邮件地址、名字等,我将存储在数据库中

当我构建允许用户编辑其个人资料的屏幕时,我希望有一个“更改密码”复选框,以便我可以显示/隐藏密码框,并且我还希望有一个“确认密码”字段,以便他们不会键入错误。我不想将这些属性存储在数据库中,它们实际上不是用户对象的一部分,因此我不希望这些字段存在于用户中。然而,许多web框架使得基于正在编辑的对象构建表单页面变得更加容易

我想解决这个问题的方法是创建User的子类,我们称之为EditableUser,它有一些额外的字段,比如“changePassword”和“confirmPassword”,并在我的表单上使用这个对象。但问题是Hibernate不知道如何保存EditableUser对象。(这也是一个如何从从数据库加载的用户创建EditableUser的问题,但如果您有一个复制构造函数,这是可行的)


我最终解决这个问题的方法是使用委托:创建一个EditableUser对象,其中包含一个用户,以及我不想保存的额外属性。这工作得相当不错,只是这意味着我在表单上的所有数据绑定都必须更改才能访问内部用户对象,所以感觉有点混乱。

有一种解决方案可以解决这个问题,这里实际上讨论了StackOverFlow:

实际上,您只需告诉Hibernate使用超类的字符串将类保存为超类,如:

save(“my.superclass”,子类)


这可能不适用于所有用例,但对我来说,这只是一张罚单。

是否实际映射了
超类?异常表明它不是.Ooops,应该是“org.hibernate.MappingException:Unknown entity:test.Subclass”。我只将数据加载到超类。如果超类添加了额外的字段,您的建议还需要通知委派的更新。