从依赖对象列表中更新一个值

时间:2009-12-11 09:42:57

标签: java hibernate hql lazy-loading

给定具有组件列表的实体:

class Entity{
    Long id;
    String name;
    List<Component> components = new ArrayList<Component>();
}
class Component{ Object value; }

配置:

<hibernate-mapping>
    <class name="Entity" table="entity">
        <id name="id" access="field" column="id"/>
        <property name="name" access="field" unique="true"/>

        <list name="components" access="field" table="COMPONENTS" lazy="true">
            <key column="id"/>
            <list-index column="idx"/>
            <composite-element class="Component">
                <property name="value" access="field"/>
            </composite-element>
        </list>
    </class>
</hibernate-mapping>

是否可以使用HQL语句(如

)更新列表中的一个组件
update Entity e set e.components[:index].value = :value where e.name = :name

哪个不起作用?

或者,是否可以以第一次访问的方式配置组件列表的延迟加载:

entity.components.get(0).value = "..";

没有加载整个列表?

修改 lazy="extra"配置适用于select(仅加载要更新的组件),但不会更新已更改的组件。

1 个答案:

答案 0 :(得分:1)

您无法通过HQL更新单个集合元素。

来自13.4. DML-style operations chapter

  • 在from-clause中只能命名一个实体。
  • 可以在批量HQL查询中指定隐式或显式的连接。

由于您的集合元素不是实体,因此无法在批量更新中进行寻址。从技术上讲,非实体收集要素一般不可寻址;带有自然id的元素的索引集合或集合是唯一的例外。

虽然可以lazy-load collection elements few at a time(虽然在这种情况下它没有用,除非你提前知道你只会看第N个元素,因为批量大小在运行时不容易改变),它不会有帮助,因为当你尝试更新它时,无论如何都会加载整个集合。

选择一个集合元素is possible for indexed collection(不是您问题的一部分,但我想根据KLE答案和您的意见澄清一下):

select c
  from Entity e join e.components c
 where index(c) = :index