nHibernate 延迟加载/代理对象 - 持久性问题

发布于 2024-08-23 01:08:37 字数 4311 浏览 10 评论 0原文

[使用映射文件更新]

今天遇到了延迟加载/代理对象持续存在的问题。

它涉及两个类:发票和地址。发票有一个地址属性。这两个类都设置为延迟加载,并且所有方法都是虚拟的。

在代码中,我执行了 Invoice.address = HomeCompany.address,并且可以在运行时验证 Invoice.address 是否设置正确(Invoice.address 属性已正确分配“地址代理”)。然而,当发票对象被持久化时,发票表中的“addresss_id”列将被设置为“0”。但是,如果我通过添加“Lazy = False”来更改地址的映射文件,一切都会正常工作(invoice.address 属性设置为完整的实例化地址)。

使用 nHibernate 2.1.2 这让我发疯。

[注意:nhibernate 不会产生任何错误]

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping default-access="field.camelcase-underscore" xmlns="urn:nhibernate-mapping-2.2">
<class name="TMS.Business.invoice, TMS.Business"  dynamic-update="true" optimistic-lock="all" table="invoice">

    <id name="document_id" type="Int32">
        <generator class="assigned" />
    </id>

    <property name="create_date" />
    <many-to-one name="last_updt_user" column="last_updt_userid"/>
    <property name="last_updt_datetime" />

    <property name="amount" />
    <property name="approved_flag"/>
    <property name="ba_document_date" />
    <property name="ba_document_no" not-null="true"/>
    <property name="comment" not-null="true"/>
    <property name="document_no" />
    <property name="document_no_construct"/>
    <property name="dry_gas_billing_date" />
    <property name="due_date" />
    <property name="fin_batch_no" />
    <property name="fin_interface_type_cd"/>
    <property name="fin_process_datetime" />        
    <property name="invoice_date" />
    <property name="netout_flag"/>
    <property name="override_amount" />
    <property name="receipt_date" />
    <property name="void_flag"/>

    <many-to-one name="accountant_user" column="accountant_userid"/> 
    <many-to-one name="ba" column="ba_id" property-ref="_ba_id" /> 
    <many-to-one name="ba_addr" column="ba_addr_id" property-ref="_ba_address_id" /> 
    <many-to-one name="ba_contact" column="ba_contact_id" property-ref="_ba_contact_id" /> 
    <many-to-one name="dry_gas_billing_type" column="dry_gas_billing_type_cd" property-ref="_code_key" />
    <many-to-one name="internal_ba" column="internal_ba_id" property-ref="_ba_id" />
    <many-to-one name="invoice_subtype" column="invoice_subtype_cd" property-ref="_code_key" />
    <many-to-one name="invoice_type" column="invoice_type_cd" property-ref="_code_key" />
    <many-to-one name="payment_method" column="payment_method_cd" property-ref="_code_key" />
    <many-to-one name="payment_term" column="payment_term_id" />
    <many-to-one name="remit_to_addr" column="remit_to_addr_id" property-ref="_ba_address_id"/>

    <bag name="document_histories" lazy="true" cascade="none" inverse="true" where ="linked_table = 'invoice'" order-by="document_history_id DESC">
        <key column="linked_pk"/>
        <one-to-many class="TMS.Business.document_history, TMS.Business"/>
    </bag>
    <bag name="trxn_pricelines" lazy="true" cascade="none" inverse="true">
        <key column="document_id"/> 
        <one-to-many class="TMS.Business.trxn_priceline, TMS.Business"/>
    </bag>      

</class>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-access="field.camelcase-underscore" xmlns="urn:nhibernate-mapping-2.2">
<class name="TMS.Business.ba_address, TMS.Business" optimistic-lock="version" table="_ba_address">

    <id name="item_guid" type="Guid">
        <generator class="guid" />
    </id>
    <version name="version" />

    <property name="active_flag" />
    <property name="address" />
    <property name="city" />
    <property name="county" />
    <property name="remarks" />
    <property name="zip" />

    <many-to-one name="business_associate" column="business_associate_guid" />
    <many-to-one name="country" column="country_code" />
    <many-to-one name="state" column="state_code" />

    <property name="_ba_address_id" generated="insert" update="false" insert="false"/>  

</class>

[Updated with mapping files]

Ran into an issue with a lazy loaded / proxied object being persisted today.

It relates to two classes, Invoice and Address. A invoice has an Address property. Both classes are setup to be lazy loaded and all methods are virtual.

In the code I do a Invoice.address = HomeCompany.address and I can verify at runtime that the Invoice.address is being set correctly (The Invoice.address property is correctly assigned an 'address proxy'). However when the Invoice object gets persisted, the 'addresss_id' columns in the invoice table is being set to '0'. If however, i change the mapping file for the address by adding 'Lazy = False' everything works just fine (the invoice.address property is set to a full instantiated address).

Using nHibernate 2.1.2 and this is driving me crazy.

[Note: nhibernate is not generating any errors]

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping default-access="field.camelcase-underscore" xmlns="urn:nhibernate-mapping-2.2">
<class name="TMS.Business.invoice, TMS.Business"  dynamic-update="true" optimistic-lock="all" table="invoice">

    <id name="document_id" type="Int32">
        <generator class="assigned" />
    </id>

    <property name="create_date" />
    <many-to-one name="last_updt_user" column="last_updt_userid"/>
    <property name="last_updt_datetime" />

    <property name="amount" />
    <property name="approved_flag"/>
    <property name="ba_document_date" />
    <property name="ba_document_no" not-null="true"/>
    <property name="comment" not-null="true"/>
    <property name="document_no" />
    <property name="document_no_construct"/>
    <property name="dry_gas_billing_date" />
    <property name="due_date" />
    <property name="fin_batch_no" />
    <property name="fin_interface_type_cd"/>
    <property name="fin_process_datetime" />        
    <property name="invoice_date" />
    <property name="netout_flag"/>
    <property name="override_amount" />
    <property name="receipt_date" />
    <property name="void_flag"/>

    <many-to-one name="accountant_user" column="accountant_userid"/> 
    <many-to-one name="ba" column="ba_id" property-ref="_ba_id" /> 
    <many-to-one name="ba_addr" column="ba_addr_id" property-ref="_ba_address_id" /> 
    <many-to-one name="ba_contact" column="ba_contact_id" property-ref="_ba_contact_id" /> 
    <many-to-one name="dry_gas_billing_type" column="dry_gas_billing_type_cd" property-ref="_code_key" />
    <many-to-one name="internal_ba" column="internal_ba_id" property-ref="_ba_id" />
    <many-to-one name="invoice_subtype" column="invoice_subtype_cd" property-ref="_code_key" />
    <many-to-one name="invoice_type" column="invoice_type_cd" property-ref="_code_key" />
    <many-to-one name="payment_method" column="payment_method_cd" property-ref="_code_key" />
    <many-to-one name="payment_term" column="payment_term_id" />
    <many-to-one name="remit_to_addr" column="remit_to_addr_id" property-ref="_ba_address_id"/>

    <bag name="document_histories" lazy="true" cascade="none" inverse="true" where ="linked_table = 'invoice'" order-by="document_history_id DESC">
        <key column="linked_pk"/>
        <one-to-many class="TMS.Business.document_history, TMS.Business"/>
    </bag>
    <bag name="trxn_pricelines" lazy="true" cascade="none" inverse="true">
        <key column="document_id"/> 
        <one-to-many class="TMS.Business.trxn_priceline, TMS.Business"/>
    </bag>      

</class>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping default-access="field.camelcase-underscore" xmlns="urn:nhibernate-mapping-2.2">
<class name="TMS.Business.ba_address, TMS.Business" optimistic-lock="version" table="_ba_address">

    <id name="item_guid" type="Guid">
        <generator class="guid" />
    </id>
    <version name="version" />

    <property name="active_flag" />
    <property name="address" />
    <property name="city" />
    <property name="county" />
    <property name="remarks" />
    <property name="zip" />

    <many-to-one name="business_associate" column="business_associate_guid" />
    <many-to-one name="country" column="country_code" />
    <many-to-one name="state" column="state_code" />

    <property name="_ba_address_id" generated="insert" update="false" insert="false"/>  

</class>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

秋叶绚丽 2024-08-30 01:08:37

如果您使用地址的主键 (id) 映射 Invoice.Address,则不会发生这种情况。

<class name="TMS.Business.invoice, TMS.Business"  dynamic-update="true" optimistic-lock="all" table="invoice">

    <id name="document_id" type="Int32">
        <generator class="assigned" />
    </id>
    <many-to-one name="ba_addr" column="ba_addr_id"  /> 
</class>

<class name="TMS.Business.ba_address, TMS.Business" optimistic-lock="version" table="_ba_address">
    <id name="item_guid" type="Guid">
        <generator class="guid" />
    </id>
</class>

所描述的行为听起来像是 _ba_address_id 被映射为字段,但您的映射文件表明它是一个属性。然而,前导下划线和小写名称表明您正在映射字段而不是属性。

如果这实际上是一个字段,那么这就是您的问题的原因。为了加载代理对象,您需要访问它的(虚拟)属性或方法之一。

This will not happen if you map Invoice.Address using the primary key (id) of address.

<class name="TMS.Business.invoice, TMS.Business"  dynamic-update="true" optimistic-lock="all" table="invoice">

    <id name="document_id" type="Int32">
        <generator class="assigned" />
    </id>
    <many-to-one name="ba_addr" column="ba_addr_id"  /> 
</class>

<class name="TMS.Business.ba_address, TMS.Business" optimistic-lock="version" table="_ba_address">
    <id name="item_guid" type="Guid">
        <generator class="guid" />
    </id>
</class>

The described behaviour sounds like _ba_address_id is mapped as a field, but your mapping file suggests it is a property. However the leading underscore and lower case names suggest you are mapping fields rather than properties.

If this is in fact a field, this is the cause of your problem. In order to load a proxy object, you need to access one of its (virtual) properties or methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文