私は、金融システムでかなり複雑なNHibernateトランザクションを実行し、支払いを作成し、元帳のエントリを記録し、支払いが請求書の合計金額であるかどうかを確認します。楽しいことがたくさん。当然、単一のトランザクション内で発生する必要があります。
セッションへの変更をコミットしようとすると、次のエラーが発生します。
Error dehydrating property value for C3.DataModel.CFAPTransaction.Vendor
これをグーグルしても、多くの記録は得られませんでした。これが何を意味し、どこにデバッグ作業を集中させる必要があるかを誰かに教えてもらえますか?
[〜#〜]更新[〜#〜]
リクエストごとに、ここに完全なエラーメッセージがあります:
NHibernate.PropertyValueException: Error dehydrating property v alue for C3.DataModel.CFAPTransaction.Vendor --->
NHibernate.HibernateException:プロパティを解決できません:NHibernate.Tuple.EntityMetamodel.GetPropertyIndex(String propertyName)のNHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity、String propertyPath)at NHibernate.Persister.Entity.Perbstract GetiberValue(Object obj、String propertyName、EntityMode entityMode)at NHibernate.Type.EntityType.GetIdentifier(Object value、ISessionImplementor session)at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st、Object value、Int32 index、Boolean [] settable、ISessionImplementorセッション)at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id、Object [] fields、Object rowId、Boolean [] includeProperty、Boolean [] [] includeColumns、Int32 table、IDbCommand statement、ISessionImplementor session、Int32 index)- -内部例外スタックトレースの終わり--- at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id、Object [] fields、Object rowId、Boolea n [] includeProperty、Boolean [] [] includeColumns、Int32テーブル、IDbCommandステートメント、ISessionImplementorセッション、Int32インデックス)at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id、Object [] fields、Boolean [] notNull、Int32 j 、SqlCommandInfo sql、Object obj、ISessionImplementorセッション)(NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id、Object [] fields、Object obj、ISessionImplementor session)at NHibernate.Action.EntityInsertAction.Execute()at NHibernate.Engine。 NHibernate.Engine.ActionQueue.ExecuteActions(IListリスト)のActionQueue.Execute(IExecutable実行可能ファイル)NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSourceセッション)のNHibernate.Engine.ActionQueue.ExecuteActions()にあります。 DefaultFlushEventListener.OnFlush(FlushEvent event)at NHibernate.Impl.SessionImpl.Flush()at NHibernate.Transaction.AdoTransaction.Commit()at C3.DataModel.Repositories.NHUnitOfWork.Save()in C:\ projects\C3\C3.Da taModel.Generated\Generated\NHibernateRepositories.generated.cs:line 2659 at C3.WebUI.Areas.Finance.Controllers.AccountsPayableController.CreatePayment(CreatePaymentModel model)in C:\ projects\C3\C3.WebUI\Areas\Finance\Controllers\AccountsPayableController.cs:line 434
[〜#〜] update [〜#〜] NHibernateをDEBUGモードにスローすると、次のようなものがたくさん得られます:
カスケードNHibernate.Engine.CascadingAction + SaveUpdateCascadingActionのカスケード処理:C3.DataModel.APVendorカスケードNHibernate.Engine.CascadingAction + SaveUpdateCascadingActionのコレクション:C3.DataModel.APVendor.Transactions完了カスケードNHibernate.Engine.CascadingAction + SaveUpdateCascadingModelのコレクション:C3.Data APVendor.TransactionsがカスケードNHibernate.Engine.CascadingAction + SaveUpdateCascadingActionの処理を完了しました:C3.DataModel.APVendor NHibernate.Event.Default.AbstractFlushingEventListenerエラーデータベースの状態をセッションと同期できませんでしたNHibernate.PropertyValueException:C3.DataModel.CFAPTransactionのプロパティ値の脱水中にエラーが発生しました。ベンダー---> NHibernate.HibernateException:プロパティを解決できません:NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName)のNHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity、String propertyPath)at NHibernate.Persister .Entity.AbstractEntityPersister.GetProp ertyValue(Object obj、String propertyName、EntityMode entityMode)at NHibernate.Type.EntityType.GetIdentifier(Object value、ISessionImplementor session)at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st、Object value、Int32 index、Boolean [] settable、ISessionImplementorセッション)at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id、Object [] fields、Object rowId、Boolean [] includeProperty、Boolean [] [] includeColumns、Int32 table、IDbCommand statement、ISessionImplementor session、Int32 index)- -内部例外スタックトレースの終わり--- at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id、Object [] fields、Object rowId、Boolean [] includeProperty、Boolean [] [] includeColumns、Int32 table、IDbCommand statement、 NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id、Object [] fields、Boolean [] notNull、Int32 j、SqlCommandInfo sql、Object obj、ISessionImplementor session)でのNHibernaでのISessionImplementorセッション、Int32インデックス) te.Persister.Entity.AbstractEntityPersister.Insert(Object id、Object [] fields、Object obj、ISessionImplementor session)at NHibernate.Action.EntityInsertAction.Execute()at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)at NHibernate.Engine .ActionQueue.ExecuteActions(IList list)at NHibernate.Engine.ActionQueue.ExecuteActions()at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)C3.WebUI.Areas.Finance.Controllers.AccountsPayableController ERROR C3.WebUI.Areas。 Finance.Controllers.AccountsPayableController:追加情報はありません。 NHibernate.PropertyValueException:C3.DataModel.CFAPTransaction.Vendorのプロパティ値の脱水エラー---> NHibernate.HibernateException:プロパティを解決できません:NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName)at NHibernate.Tuple.EntityでAPVendorId NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Object obj、String propertyName、EntityMode entityMode)のNHibernate.Type.EntityType.GetIdentifier(Object value、ISessionImplementor session)のNHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValueの.AbstractEntityTuplizer.GetPropertyValue(Object entity、String propertyPath) .ManyToOneType.NullSafeSet(IDbCommand st、Object value、Int32 index、Boolean [] settable、ISessionImplementor session)at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id、Object [] fields、Object rowId、Boolean [] includeProperty、Boolean [] [] includeColumns、Int32テーブル、IDbCommandステートメント、ISessionImplementorセッション、Int32インデックス)---内部例外スタックトレースの終了--- NHibernate.PersisterのNHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id、Object [] fields、Object rowId、Boolean [] includeProperty、Boolean [] [] includeColumns、Int32 table、IDbCommand statement、ISessionImplementor session、Int32 index) .Entity.AbstractEntityPersister.Insert(Object id、Object [] fields、Boolean [] notNull、Int32 j、SqlCommandInfo sql、Object obj、ISessionImplementor session)at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id、Object [] fields 、Object obj、ISessionImplementor session)at NHibernate.Action.EntityInsertAction.Execute()at NHibernate.Engine.ActionQueue.Execute(IExecutable executable)at NHibernate.Engine.ActionQueue.ExecuteActions(IList list)at NHibernate.Engine.ActionQueue.ExecuteActions( )NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)at NHibernate.Impl.SessionImpl.Flush()at NHiber nate.Transaction.AdoTransaction.Commit()at C3.DataModel.Repositories.NHUnitOfWork.Save()in C:\ projects\C3\C3.DataModel.Generated\Generated\NHibernateRepositories.generated.cs:line 2659 at C3.WebUI。 Areas.Finance.Controllers.AccountsPayableController.CreatePayment(CreatePaymentModel model)in C:\ projects\C3\C3.WebUI\Areas\Finance\Controllers\AccountsPayableController.cs:line 434
これは、データベースのクエリ時に発生しているようには見えません。オブジェクトの束を作成し、それらを関連付けてから永続化しようとすると問題があるように感じますが、それは純粋な推測です。
Nhibernateがエラーの正しいプロパティを表示していない可能性があります。マッピングファイルの隣接するプロパティを確認し、データベースのデータ型と.netのデータ型またはプロパティの繰り返し列の関係にエラーがないか確認してください...また、これも確認してくださいリンク 流暢NHibernate-IndexOutOfRange
CFAPTransactionマッピングを確認する必要があります。トランザクションごとに1つのベンダーを指定したいようです。この場合、マッピングは以下のコードのようにする必要があります。
public CFAPTransactionMap()
{
HasOne(x => x.Vendor).ForeignKey("VendorId").Cascade.All();
...
}
私の場合、それはSQL Serverで欠落しているID仕様でした。
単純なオブジェクト:
public class Employee
{
public virtual int ID { get; set; }
}
マッピング:
public class EmployeeMap : ClassMapping<Employee>
{
public EmployeeMap()
{
Id(x => x.ID, map => { map.Generator(Generators.Identity); map.UnsavedValue(0); });
}
}
SQL:
これは、主キー制約のあるID列です。
そして、ここで問題の原因となっている欠落しているID仕様を確認できます。
この問題を解決するには、ID列をIDENTITY
として指定する必要があります。
CREATE TABLE EMPLOYEE
(
ID int NOT NULL IDENTITY(0, 1)
);
同じエラーが発生しました。これは私のサンプルマッピングです:
ManyToOne(x => x.objPerson, map => { map.Column("PersonID"); map.NotNullable(false); });
Property(x => x.intPersonID, map => map.Column("PersonID"));
プロパティintPersonID
のみを入力し、objPerson
をnullにしてデータベースに永続化/保存しようとすると、すべてのプロパティで脱水エラーが発生します。
私がintPersonID
に入力しているのは、データベースに保存する前に、データベースでクエリを実行してobjPerson
を取得しないようにするためです。残念ながら、エラーが発生するので、マッピングを変更して修正しました。
ManyToOne(x => x.objPerson, map => { map.Column("PersonID"); map.NotNullable(false); });
または、オブジェクト全体を取得してデータベースでクエリを実行しないようにする場合は、代わりにこのマッピングを使用します。
Property(x => x.intPersonID, map => map.Column("PersonID"));
しかし、それらを組み合わせることはできません。
かつて賢い人がこれを私のマッピングに追加するように言った
.Length(int.MaxValue);
私の場合、例外はエラーの原因であるプロパティを正確に特定することでした。私にはcascade
定義が欠けていた多対1のプロパティがありました。 "save-update"
はエラーを防ぎます:
<many-to-one name="FocusType" cascade="save-update"
class="MyInfrastructure.FocusType, MyInfrastructure">
<column name="FocusTypeId" sql-type="int" not-null="false" />
</many-to-one>