Arm*_*and 5 java orm persistence hibernate table-per-hierarchy
我有一个使用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;
}
Run Code Online (Sandbox Code Playgroud)
我已经添加了A的子类,称为B:
@Entity
public class B extends A {
public String description;
}
Run Code Online (Sandbox Code Playgroud)
添加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)
Run Code Online (Sandbox Code Playgroud)
我将以下注释和属性添加到B,它似乎已经解决了问题.这是解决问题的正确方法吗?
...
@DiscriminatorFormula("(CASE WHEN dtype IS NULL THEN 'A' ELSE dtype END)")
public class A {
private String dtype = this.getClass().getSimpleName();
...
Run Code Online (Sandbox Code Playgroud)
\n\n\n(...) 直到最近,应用程序中还有一个持久类 A:
\n
具有以下数据库表示:
\n\nID NAME\n-- ----\n 1 foo\n 2 bar\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n我添加了 A 的一个子类,称为 B (...)
\n
并且您没有指定注释,Inheritance因此SINGLE_TABLE使用映射策略。在此策略中,层次结构中的所有类都映射到单个表。该表有一列用作 \xe2\x80\x9c 鉴别器列\xe2\x80\x9d,即该列的值标识该行所表示的实例所属的特定子类。
那么该表就变成了:
\n\nID NAME DTYPE\n-- ---- -----\n 1 foo NULL\n 2 bar NULL\nRun Code Online (Sandbox Code Playgroud)\n\n其中 DTYPE 是用于鉴别器的列的默认名称。
\n\n\n\n\n添加 B 后,我现在无法加载 A 的。抛出了以下异常(...)
\n
事实上,由于现有值在鉴别器列中具有空值,因此提供程序不知道要实例化哪个子类。
\n\n\n\n\n我在B中添加了以下注释和属性,似乎已经解决了问题。这是解决问题的正确方法吗?
\n
这是一种方式,但它是侵入性的(您的实体不应该知道该dtype列)并且是 Hibernate 特定的。换句话说,这是一个黑客行为。
对我来说,解决这个问题的“正确”方法是更新DTYPE现有 A 记录的列以将值设置为\'A\'(使用 Hibernate,该值默认为实体名称):
UPDATE A SET DTYPE=\'A\' WHERE DTYPE=NULL\nRun Code Online (Sandbox Code Playgroud)\n\n这样,Hibernate 将能够正确加载它们。
\n| 归档时间: |
|
| 查看次数: |
3837 次 |
| 最近记录: |