使用 DiscriminatorFormula 迁移 Hibernate 数据库是一种不好的做法吗?
我有一个使用 Hibernate 进行数据持久化的应用程序,并使用 Spring(为了更好的衡量标准)。直到最近,应用程序中存在一个持久类,A:
@Entity
public class A {
@Id
@Column(unique = true, nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
public String name;
}
此后我添加了 A 的一个子类,称为 B:
@Entity
public class B extends A {
public String description;
}
添加 B 后,我现在无法加载 A 的。抛出了以下异常:
class org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException :: Object with id: 1 was not of the specified subclass: A (Discriminator: null); nested exception is org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: A (Discriminator: null)
我在B中添加了以下注释和属性,似乎已经解决了问题。这是解决问题的正确方法吗?
...
@DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'A' ELSE dtype END)")
public class A {
private String dtype = this.getClass().getSimpleName();
...
I have an application using Hibernate for data persistence, with Spring on top (for good measure). Until recently, there was one persistent class in the application, A:
@Entity
public class A {
@Id
@Column(unique = true, nullable = false, updatable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
public String name;
}
I have since added a subclass of A, called B:
@Entity
public class B extends A {
public String description;
}
After adding B, I could now not load A's. The following exception was thrown:
class org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException :: Object with id: 1 was not of the specified subclass: A (Discriminator: null); nested exception is org.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: A (Discriminator: null)
I added the following annotation and property to B, and it seems to have solved the problem. Is this the right way to solve the issue?
...
@DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'A' ELSE dtype END)")
public class A {
private String dtype = this.getClass().getSimpleName();
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
具有以下数据库表示形式:
并且您没有指定
继承
注释,因此使用SINGLE_TABLE
映射策略。 在此策略中,层次结构中的所有类都映射到单个表。该表有一列用作“鉴别器列”,即该列的值标识该行所表示的实例所属的特定子类。该表变为:
其中 DTYPE 是用于鉴别器的列的默认名称。
确实,因为现有值在鉴别器列中具有空值,所以提供程序不知道要实例化哪个子类。
这是一种方法,但它是侵入性的(您的实体不应该知道
dtype
列)并且是 Hibernate 特定的。换句话说,这是一个黑客行为。对我来说,解决这个问题的“正确”方法是更新现有 A 记录的
DTYPE
列,将值设置为'A'
(使用 Hibernate,该值默认为实体名称):这样,Hibernate 将能够正确加载它们。
With the following database representation:
And you didn't specify the
Inheritance
annotation so theSINGLE_TABLE
mapping strategy is used. And In this strategy, all the classes in a hierarchy are mapped to a single table. The table has a column that serves as a “discriminator column”, that is, a column whose value identifies the specific subclass to which the instance that is represented by the row belongs.The table then became:
Where DTYPE is the default name of column to be used for the discriminator.
Indeed, because existing values have a null value in the discriminator column, the provider doesn't know what subclass to instantiate.
That's one way but it is intrusive (your entities shouldn't be aware of the
dtype
column) and Hibernate specific. In other words, it's a hack.For me, the "right" way to solve this would be to update the
DTYPE
column of existing A records to set the value to'A'
(with Hibernate, the value defaults to the entity name):This way, Hibernate would be able to load them properly.