我有一个Hibernate实体,它有一个或多个<many-to-one
映射,例如
<hibernate-mapping>
<class name="MyClass" table="my_table">
<cache usage="nonstrict-read-write"/>
<composite-id>
<key-property name="id" length="30"/>
<key-property name="someRef" length="30" column="foreign_key_to_something"/>
</composite-id>
<many-to-one name="mappedProperty" column="foreign_key_to_something" insert="false" update="false"/>
<property name="foo" column="foo"/>
...
</class>
</hibernate-mapping>
我需要创建这样一个实体,并在创建后立即访问mappedProperty
。我可以在这里看到两种方法:
1)创建实体并手动设置所有相关的<many-to-one
映射。这种方法的明显缺点是需要腿部工作,特别是如果映射的<many-to-one
实体的数量很高。如果框架可以为您做什么,为什么要手动执行?
2)仅通过初始化必要参数(例如上述情况中的主键,id
和someRef
)创建实体,然后立即保存并重新加载。加载应自动初始化mappedProperty
或按需提供延迟初始化。
我更喜欢选项2),但是,我注意到在某些情况下,mappedProperty
属性未设置。 load()
返回我传递给create()
的同一个对象,只初始化了主键。我仍然不确定为什么会发生这种情况,但为了对抗它,我必须将对象从Hibernate会话中分离出来,以便load()
被强制转到数据库并重新获得。再一次,听起来相当复杂,不是吗?
我在这里遗漏了什么吗?还有其他方法可以解决这个问题吗?
答案 0 :(得分:3)
当您需要从数据库刷新对象的状态时,请使用refresh()
。
答案 1 :(得分:1)
load
和get
会从会话中返回该对象(如果已存在)。因此,您的第二个选项需要刷新,然后从会话中删除实体,然后重新加载它(为您知道的数据发出选择查询)。对刷新的调用会更容易地执行相同操作,但仍会发出额外的选择查询。
我更喜欢第一个选项:只需确保每次设置关联,然后映射相应的映射属性。您负责实体的一致性和不变性(与双向关联一样,必须维护双方)。
第三个选项是完全删除映射的属性,只需调用entity.getKey()。getSomeRef()。getId()。