【问题标题】:hibernate empty collection in component休眠组件中的空集合
【发布时间】:2011-02-16 17:27:31
【问题描述】:

我有一个使用 Hibernate 映射的组件。如果数据库中组件的所有字段都为null,则组件本身被hibernate设置为null。这是预期的行为,也是我需要的。

我遇到的问题是,当我向该组件添加一个包时,该包被初始化为一个空列表。这意味着组件具有非 null 值...导致组件被创建。

知道如何解决这个问题吗?

<class name="foo.bar.Entity" table="Entity">
<id name="id" column="id">
    <generator class="native" />
</id>

<property name="departure" column="departure_time" />
<property name="arrival" column="arrival_time" />

<component name="statistics">
    <bag name="linkStatistics" lazy="false" cascade="all" >
        <key column="entity_id" not-null="true" />
        <one-to-many class="foo.bar.LinkStatistics" />
    </bag>

    <property name="loggedTime" column="logged_time" />

    ...
</component>

带有 Restirctions.isNull("statistics") 的条件确实会返回预期值。

【问题讨论】:

  • 请添加有关上下文的信息:谁将组件设置为空?你说的是哪个组件?哪个是容器?
  • Aaron,Hibernate 将组件属性(统计,在 Entity 类中)保留为 null。
  • 似乎是一个相当老的问题,但我也有它,但找不到任何解决方案。这段时间你运气好吗?
  • 你的包的惰性属性是否必须设置为false?

标签: hibernate null components bag


【解决方案1】:

这里的基本问题是Hibernate无法区分空集合和空集合,所以它把它们都当作空:非空。

我建议您改为将您的统计组件更改为真实实体。然后你的 foo.bar.Entity 类有一个引用,它可以是空的。这并不理想,因为您必须创建另一个表来存储 Statistics 实体,但如果您想要 null 与空的语义区别,这是一种获得它的方法。

【讨论】:

  • 正确。集合的概念在 RDBMS 中并不真正存在,因此 Hibernate(或任何 ORM)必须做一些事情
【解决方案2】:

我无法验证这一点,但这是一个想法:

public void setListProperty(List list) {
  if (list == null || list.size() == 0) {
    this.listProperty = null;
  } else {
    this.listProperty = list;
  }
}

显然不理想,但可能是您的解决方法...

【讨论】:

  • 这种方法真的适合你吗?根据我的经验,setter 中的这些技巧会导致 Hibernate 中出现异常“另一个集合已与会话关联”(因为 Hibernate 会记住它打算与父实体关联的空集合)。因此,当实体分离(加载它的会话已关闭)时,上面的代码将起作用,否则将失败。在 getter 中使用 null 会好得多:)
【解决方案3】:

也许这会有所帮助。它不能解决区分空包和空包的问题,​​但它是一种解决方法。 正如您可能知道的那样,您可以在会话中引入一个拦截器,该拦截器可以拦截某些操作,例如保存或更新实体,然后您可以使用此拦截器检查组件的状态,如果它为空,则再次将其设为 null,以便休眠不会t 保存空值。 here 的文档。

【讨论】:

    猜你喜欢
    • 2011-03-26
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    • 2011-02-25
    • 2011-12-02
    • 2013-03-20
    • 1970-01-01
    相关资源
    最近更新 更多