Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate交换出可嵌入类以迁移现有数据_Hibernate_Migrate_Embeddable - Fatal编程技术网

Hibernate交换出可嵌入类以迁移现有数据

Hibernate交换出可嵌入类以迁移现有数据,hibernate,migrate,embeddable,Hibernate,Migrate,Embeddable,我在这里不知所措,也许这是显而易见的,因为我的Hibernate技能比其他领域弱 在遗留代码中有一个Hibernate@实体classFoo。其特性之一是: private OldBar bar = new OldBar(); OldBar是一个@可嵌入的类,它使用单个列foobar: @Embeddable public class OldBar { private String fooBar; @Column(length = 10, nullable = false) p

我在这里不知所措,也许这是显而易见的,因为我的Hibernate技能比其他领域弱

在遗留代码中有一个Hibernate
@实体
class
Foo
。其特性之一是:

private OldBar bar = new OldBar();
OldBar
是一个
@可嵌入的
类,它使用单个列
foobar

@Embeddable
public class OldBar {

  private String fooBar;

  @Column(length = 10, nullable = false)
  private String getFooBar() {
    return fooBar;
  }

  @SuppressWarnings("unused")
  private void setFooBar(String fooBar) {
    this.fooBar = fooBar;
  }
}
最初的问题是我需要使用
OldBar.fooBar
,但是最初的设计有一些限制,并且这个字段是私有的,阻止了我对它进行子类化,所以我必须创建一个完整的另一个类,
NewBar
,来替换另一个类并访问私有字段。我想既然
NewBar
也是
可嵌入的
,并且具有相同的
@列
名称,我可以交换类
Foo
中的字段:

private NewBar bar = new NewBar();
我之所以想这样做,是因为我在
foobar
列中有现有数据,并且我想将此数据透明地与
NewBar
一起使用,而不是
OldBar

通过跟踪日志,我看到当调用构造函数时,
Foo()
被创建,其默认版本为
NewBar()
。但是,当代码调用
Foo.getBar()
时,由于某种原因
bar
null
!我假设Hibernate出于某种原因将其设置为
null
——但是为什么Hibernate不从
foobar
列读取数据并创建
NewBar
的实例呢?为什么当我把
OldBar
放回
NewBar
的位置时,它又开始工作了?当然,数据库本身没有说明哪个
@embeddeble
类映射到列,是吗

更新:这变得越来越陌生。有时我会让代码在一夜之间运行,第二天就可以了!或者第二天就不行了!刚才它不起作用(也就是说,
foobar
属性被设置为
null
,而不是数据库中的值),所以我创建了class
ExactCopyOfOldBar
,并将其放置在
OldBar
的位置。它工作得很好!因此,我切换回
NewBar
——只是撤销临时更改。它仍然有效,以前没有!是否存在某种缓存,Hibernate在其中序列化值而不从数据库获取它们?这很奇怪

更新:现在我再也不能让
NewBar
工作了。我创建了
OtherBar
,它基本上与
NewBar
相同,只是它有一个不同的名称,我将它插入并正常工作,正确读取嵌入的字符串。我切换回
NewBar
,再次得到
null
。发生了什么事

请注意,
Foo
是通过
net.databinder.auth.hib.AuthDataApplication.getUser(字符串用户名)
加载的,这非常简单:

return (DataUser) Databinder.getHibernateSession().createCriteria(getUserClass())
    .add(Restrictions.eq("username", username)).uniqueResult();

我反复验证了
Foo
(用户)表中有一行数据正确,最重要的是
foobar
字段中有数据。为什么Hibernate会返回一个带有
null
foobar
字段的
Foo
?为什么简单地从
NewBar
切换到
OtherBar
会让它重新开始工作?为什么它工作了一整天,然后在我离开它过夜后就停止工作了?

这可能就是答案;我得等几天,看看它是否真的解决了这个问题。实际上有两部分

首先,为了充分披露,我的
NewBar
类实际上是
AbstractBar
的一个子类。我最终希望有不同类型的可嵌入条,因此我将
@embeddeble
放在
AbstractBar
级别,而不是
NewBar
级别,并将私有
foobar
字段也放在
AbstractBar
级别。有趣的是,这在某些时候奏效了。正如我提到的,有时候我第二天回来,Hibernate不会加载
foobar
字段。我不明白为什么它不是一直工作就是一直不工作

其次,当我试图摆脱这种层次结构以消除问题的一个根源时,我将
AbstractBar
NewBar
混为一谈,但忘了将
@embeddeble
AbstractBar
提升到
NewBar
,所以Hibernate没有看到这是一个可嵌入类,并且不知道如何在没有
@embeddedable
指定的情况下将字符串加载到
NewBar
字段中。这就是为什么
OtherBar
(带有
@embeddeble
注释)起作用,而不是
NewBar
(没有
@embeddeble
注释)。这一点我很理解。我不知道为什么Hibernate没有警告我它无法确定如何加载字段


总之,如果您将
@embeddeble
注释从类中移除,Hibernate将不会加载可嵌入字段。至于最初的问题,我只能猜测当试图在类层次结构上使用它时,
@embeddeble
是不可靠的,最好将所有可嵌入字段保持在可嵌入类的一个级别上。我希望这就是问题所在。我们明天看它是否继续工作。

我假设这是真的,但你没有说:
Foo.bar
标记为
@Embedded
?@Tim Pote:事实上,奇怪的是,在原始(工作)遗留代码中,它没有标记为
@Embedded
。当我将表单
OldBar
更改为
NewBar
时,我尝试了
@Embedded
和不使用
@Embedded
的方法,但没有任何区别。@Tim Pote:我从休眠中了解到,“…如果属性的类型被注释为@Embedded,则映射为@Embedded”,因此从技术上讲
@Embedded
部分是可选的。