6

我在这里不知所措,也许这很明显,因为我的 Hibernate 专业知识比其他领域要弱。

在遗留代码中有一个 Hibernate@EntityFoo。它的属性之一是:

private OldBar bar = new OldBar();

OldBar是一个@Embeddable使用单列的类,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来替换另一个并访问私人领域。我认为既然NewBaris 也Embeddable具有相同的@Column名称,我可以换掉类中的字段Foo

private NewBar bar = new NewBar();

我想这样做是因为我在foobar列中有现有数据,并且我想透明地使用这些数据NewBar而不是OldBar.

通过跟踪日志,我看到它是在调用构造函数时创建的,正如人们所期望的那样,Foo()它的默认版本是 。NewBar()但是,按时间码来电Foo.getBar(),不知bar为何null!我假设 Hibernatenull出于某种原因将其设置为 --- 但为什么 Hibernate 不从foobar列中读取数据并创建一个实例NewBarOldBar为什么当我放回原位时它又开始工作了NewBar?当然,数据库本身没有说明哪些@Embeddable类映射到列,是吗?

更新:这变得越来越陌生。有时我会让代码过夜,第二天它就可以工作了!或者第二天就不行了!刚才不行(就是把foobar属性设置为,null而不是数据库中的值),所以我做了class ExactCopyOfOldBar,把OldBar. 效果很好!所以我切换回NewBar--- 只是撤销我的临时更改。它仍然有效,以前没有!是否存在某种缓存,其中 Hibernate 序列化值并且不从数据库中获取它们?这很奇怪。

更新:现在我根本不能NewBar上班了。我创建了 ,除了它有一个不同的名称之外,它OtherBar基本上相同,我将它插入并且它可以正常工作,正确读取嵌入的字符串。NewBar我切换回NewBar,我又得到null了。到底是怎么回事?

请注意,Foo正在通过 加载net.databinder.auth.hib.AuthDataApplication.getUser(String username),这很简单:

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

我一遍又一遍地验证Foo(用户)表有一行包含正确的数据,最重要的是该foobar字段有数据。为什么 Hibernate 给我Foo一个null foobar字段?为什么简单地从切换NewBarOtherBar使其重新开始工作?为什么它一整天都在工作,然后我一夜之间就停止工作了?

4

1 回答 1

1

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

首先,为了充分披露,我的NewBar课程实际上是AbstractBar. 我最终想要有不同类型的可嵌入条,所以我放置@EmbeddableAbstractBar关卡上,而不是在NewBar关卡上,并将私有foobar字段也放在AbstractBar关卡上。有趣的是,这在某些时候奏效了。正如我所提到的,有时我会在第二天回来,而 Hibernate 不会加载该foobar字段。我不明白为什么它不是一直有效或一直无效。

其次,当我试图摆脱这种层次结构以消除问题的一个根源时,我混淆了AbstractBarNewBar但忘记将@Embeddableup from AbstractBarto提出来NewBar,所以 Hibernate 没有看到这是一个可嵌入的类,也不知道如何在没有指定的情况下将字符串加载到NewBar字段中。@Embeddable这就是为什么OtherBar(有@Embeddable注释)有效,但没有NewBar(没有@Embeddable注释)。这点我明白了。为什么 Hibernate 没有警告我它无法弄清楚如何加载字段,我不知道。

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

于 2012-04-22T17:23:19.487 回答