简体   繁体   English

使用Hibernate将子类保持为超类

[英]Persist subclass as superclass using Hibernate

I have a subclass and a superclass. 我有一个子类和一个超类。 However, only the fields of the superclass are needed to be persist. 但是,只需要保留超类的字段。

session.saveOrUpdate((Superclass) subclass);

If I do the above, I will get the following exception. 如果我这样做,我将得到以下异常。

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)

How can I persist a subclass as a superclass? 如何将子类作为超类保留? I do not prefer creating a superclass instance and then passing the values from the subclass instance. 我不喜欢创建超类实例,然后从子类实例传递值。 Because, it is easy to forget updating the logic if extra fields are added to superclass in the future. 因为,如果将来将额外字段添加到超类,很容易忘记更新逻辑。

There is a type of solution to this problem, and it's actually covered here on StackOverFlow: 这个问题有一种解决方案,它实际上在StackOverFlow中有所涉及:

Hibernate/NHibernate : how to persist subclass as instance of superclass Hibernate / NHibernate:如何将子类作为超类的实例持久化

Hibernate Documentation Hibernate文档

Essentially you just tell Hibernate to save your class as the superclass using a string for the superclass like: 基本上你只是告诉Hibernate使用超类的字符串将你的类保存为超类,如:

session.save("my.superclass",subclass); session.save( “my.superclass”,子类);

This might not work in all use cases, but for me it was just the ticket. 这可能不适用于所有用例,但对我来说只是票证。

What you try to achieve will cause you a lot of problems. 你试图实现的将会给你带来很多问题。 Just imagine what happens if you load the data again. 试想一下,如果再次加载数据会发生什么。 Which class is Hibernate supposed to use? Hibernate应该使用哪个类? The superclass? 超类? Or one of the subclasses? 或者其中一个子类? Which one? 哪一个?

I suggest to map the superclass directly and then use the delegate pattern to implement the extended functionality (basically turning your superclass in a data object which gets passed to "worker" instances). 我建议直接映射超类,然后使用委托模式来实现扩展功能(基本上将您的超类转换为传递给“worker”实例的数据对象)。

I am also interested in finding out a way to do this. 我也有兴趣找到一种方法来做到这一点。 Here is a motivating case. 这是一个激励人心的案例。 Let's say I have a User object to represent a user in my application. 假设我有一个User对象来代表我的应用程序中的用户。 The User object has a handful of properties, like username, password, email address, first name, etc that I will store in a database. User对象有一些属性,如用户名,密码,电子邮件地址,名字等,我将存储在数据库中。

When I am building the screen that lets a user edit their own profile, I want to have a check box for "Change Password", so that I can show / hide the password box, and I also want a "confirm password" field so they don't mis-type it. 当我构建允许用户编辑自己的配置文件的屏幕时,我想要一个“更改密码”的复选框,这样我就可以显示/隐藏密码框,而且我还想要一个“确认密码”字段他们不会错误地输入它。 I don't want to store these properties in the database, and they aren't really part of the User object, so I don't want those fields to exist in the User. 我不想将这些属性存储在数据库中,并且它们实际上不是User对象的一部分,因此我不希望这些字段存在于User中。 However, a lot of web frameworks make it much easier to build a form page based on an object that is being edited. 但是,许多Web框架使基于正在编辑的对象构建表单页面变得更加容易。

The way I would like to solve this is to make a subclass of User, let's call it EditableUser, which has a few extra fields like "changePassword" and "confirmPassword", and use this object on my form. 我想解决这个问题的方法是创建User的子类,让我们称之为EditableUser,它有一些额外的字段,如“changePassword”和“confirmPassword”,并在我的表单上使用这个对象。 But the problem is that Hibernate will not know how to save an EditableUser object. 但问题是Hibernate不知道如何保存EditableUser对象。 (It's also a problem of how to create an EditableUser from a User that you load from the database, but this is doable if you have a copy constructor) (这也是如何从您从数据库加载的用户创建EditableUser的问题,但如果您有一个复制构造函数,这是可行的)

The way I have ended up working around this problem is to use delegation: create an EditableUser object that has a User inside of it, along with the extra properties that I don't want to save. 我最终解决这个问题的方法是使用委托:创建一个EditableUser对象,其中包含一个User,以及我不想保存的额外属性。 This works reasonably well, except that it means that all of my data binding on the form has to change to access the inner User object, so it feels kind of messy. 这样做效果相当不错,除了它意味着我在表单上绑定的所有数据都必须更改以访问内部User对象,因此感觉有点混乱。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Hibernate / NHibernate:如何将子类持久化为超类的实例 - Hibernate/NHibernate : how to persist subclass as instance of superclass Hibernate Java 从持久化的超类中持久化一个子类实体 - Hibernate Java persist a subclass entity from persisted superclass 使用休眠保持基类和子类 - Persist base and subclass with hibernate 使用Hibernate来保存具有超类类型的一对多列表 - Using Hibernate to persist a one-to-many list with a superclass type 如何防止子类使用 Hibernate 从超类继承字段? - How to prevent a subclass from inheriting a field from the superclass using Hibernate? 在休眠中使用继承将对象从子类表复制到超类表 - using inheritance in hibernate to copy object from a subclass table to a superclass table Hibernate:超类映射到子类中的@UniqueConstraint - Hibernate: @UniqueConstraint in superclass mapping to subclass 休眠-使用每个子类的表-如何将现有的超类对象链接到子类对象 - Hibernate -using Table per subclass - how to link an existing superclass object to a subclass object 在Hibernate中是否可以通过OneToOne关系映射超类和子类? - Is it possible to map a superclass and subclass by OneToOne relationship in Hibernate? 将超类和子类映射到Hibernate中的不同表 - Map superclass and subclass to different tables in Hibernate
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM