我正在使用 OrchardCMS (1.10.x) 作为 Web 应用程序。 OrchardCMS 使用整数字段作为数据库的主键(ContentItemRecord.Id)。然而,很快,Web 应用程序将需要的不仅仅是传递 int32.MaxValue 的最大值 (2.147.483.647)。为了不破坏生产环境,我们需要OrchardCMS支持long值而不是int32。
我已经开始做这项工作并重构所有应用程序以使用长值。但是,在某些操作中我收到以下错误:
NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave.
Type: App.Core.Models.XPTOPartRecord, Entity: App.Core.Models.XPTOPartRecord
at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)
at NHibernate.Type.ManyToOneType.IsDirty(Object old, Object current, Boolean[] checkable, ISessionImplementor session)
at NHibernate.Type.TypeHelper.FindDirty(StandardProperty[] properties, Object[] currentState, Object[] previousState, Boolean[][] includeColumns, Boolean anyUninitializedProperties, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.FindDirty(Object[] currentState, Object[] previousState, Object entity, ISessionImplementor session)
at NHibernate.Event.Default.DefaultFlushEntityEventListener.DirtyCheck(FlushEntityEvent event)
at NHibernate.Event.Default.DefaultFlushEntityEventListener.IsUpdateNecessary(FlushEntityEvent event, Boolean mightBeDirty)
at NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event)
at NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event)
at NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces)
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results)
at NHibernate.Impl.CriteriaImpl.List(IList results)
at NHibernate.Impl.CriteriaImpl.List[T]()
at Orchard.ContentManagement.DefaultContentQuery.Slice(Int32 skip, Int32 count) in C:\App\src\Orchard\ContentManagement\DefaultContentQuery.cs:line 191
at Orchard.ContentManagement.DefaultContentQuery.ContentQuery`1.Orchard.ContentManagement.IContentQuery<T>.List() in C:\App\src\Orchard\ContentManagement\DefaultContentQuery.cs:line 292
at App.Core.Services.Service.GetData(string val)
at App.Core.Services.Service.Create(List`1 obj)
at App.Api.Controllers.Create(List`1 obj)
我的对象是这样声明的(id来自OrchardCMS),并且我在NHibernate上没有任何特定配置。
// From OrchardCMS
public abstract class ContentPartRecord
{
public virtual long Id { get; set; }
[CascadeAllDeleteOrphan]
public virtual ContentItemRecord ContentItemRecord { get; set; }
}
public abstract class BasePartRecord : ContentPartRecord
{
public virtual string UUID { get; set; }
public virtual DateTime? Created { get; set; }
public virtual string Name { get; set; }
// Some other props
}
public class XPTOPartRecord : BasePartRecord
{
public XPTOPartRecord()
{
}
public virtual bool Flag { get; set; }
public virtual string Status { get; set; }
public virtual XPTOPartRecord ParentXPTOPartRecord { get; set; }
// Some other props (not referenced props)
}
这只发生在将 de Id 从 INT32 更改为 LONG 后。为了解决这个问题,我激活了 NHibernate 日志并跟踪 NHibernate 内部发生的情况。大多数日志都是相等的,除了这个:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
INT VALUES
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-11-08 21:15:44,715 [22] NHibernate.Event.Default.AbstractFlushingEventListener - Default - Flushing entities and processing referenced collections
2023-11-08 21:15:44,718 [22] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#17314], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#17314] (uninitialized)
2023-11-08 21:15:44,721 [22] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#18544], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#18544] (uninitialized)
2023-11-08 21:15:44,723 [22] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#2011389097], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#2011389097] (initialized)
2023-11-08 21:15:44,724 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - Orchard.ContentManagement.Records.ContentItemVersionRecord.Published is dirty
2023-11-08 21:15:44,726 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - Orchard.ContentManagement.Records.ContentItemVersionRecord.Latest is dirty
2023-11-08 21:15:44,727 [22] NHibernate.Event.Default.DefaultFlushEntityEventListener - Default - Updating entity: [Orchard.ContentManagement.Records.ContentItemVersionRecord#2011389098]
2023-11-08 21:15:44,729 [22] NHibernate.Engine.Collections - Default - Collection found: [App.Core.Models.ControlPartRecord.Entries#2011389097], was: [App.Core.Models.ControlPartRecord.Entries#2011389097] (initialized)
2023-11-08 21:15:44,718 [22] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#17314], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#17314] (uninitialized)
2023-11-08 21:15:44,721 [22] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#18544], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#18544] (uninitialized)
2023-11-08 21:15:44,723 [22] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#2011389097], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#2011389097] (initialized)
2023-11-08 21:15:44,724 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - Orchard.ContentManagement.Records.ContentItemVersionRecord.Published is dirty
2023-11-08 21:15:44,726 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - Orchard.ContentManagement.Records.ContentItemVersionRecord.Latest is dirty
2023-11-08 21:15:44,727 [22] NHibernate.Event.Default.DefaultFlushEntityEventListener - Default - Updating entity: [Orchard.ContentManagement.Records.ContentItemVersionRecord#2011389098]
2023-11-08 21:15:44,729 [22] NHibernate.Engine.Collections - Default - Collection found: [App.Core.Models.ControlPartRecord.Entries#2011389097], was: [App.Core.Models.ControlPartRecord.Entries#2011389097] (initialized)
2023-11-08 21:15:44,730 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop1 is dirty // <-- here
2023-11-08 21:15:44,731 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop2 is dirty // <-- here
2023-11-08 21:15:44,733 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop3 is dirty // <-- here
2023-11-08 21:15:44,735 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop4 is dirty // <-- here
2023-11-08 21:15:44,738 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop5 is dirty // <-- here
2023-11-08 21:15:44,740 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop6 is dirty // <-- here
2023-11-08 21:15:44,741 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop7 is dirty // <-- here
2023-11-08 21:15:44,742 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop8 is dirty // <-- here
2023-11-08 21:15:44,743 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop9 is dirty // <-- here
2023-11-08 21:15:44,745 [22] NHibernate.Persister.Entity.AbstractEntityPersister - Default - App.Core.Models.XPTOPartRecord.Prop10 is dirty // <-- here
2023-11-08 21:15:44,746 [22] NHibernate.Event.Default.DefaultFlushEntityEventListener - Default - Updating entity: [App.Core.Models.XPTOPartRecord#2011389097] // <-- here
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LONG VALUES
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2023-11-08 21:05:47,970 [49] NHibernate.Event.Default.AbstractFlushingEventListener - Default - Flushing entities and processing referenced collections
2023-11-08 21:05:47,972 [49] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#17314], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#17314] (uninitialized)
2023-11-08 21:05:47,975 [49] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#18544], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#18544] (uninitialized)
2023-11-08 21:05:47,978 [49] NHibernate.Engine.Collections - Default - Collection found: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#2011389093], was: [Orchard.ContentManagement.Records.ContentItemRecord.Versions#2011389093] (initialized)
2023-11-08 21:05:47,980 [49] NHibernate.Persister.Entity.AbstractEntityPersister - Default - Orchard.ContentManagement.Records.ContentItemVersionRecord.Published is dirty
2023-11-08 21:05:47,981 [49] NHibernate.Persister.Entity.AbstractEntityPersister - Default - Orchard.ContentManagement.Records.ContentItemVersionRecord.Latest is dirty
2023-11-08 21:05:47,983 [49] NHibernate.Event.Default.DefaultFlushEntityEventListener - Default - Updating entity: [Orchard.ContentManagement.Records.ContentItemVersionRecord#2011389094]
2023-11-08 21:05:47,984 [49] NHibernate.Engine.Collections - Default - Collection found: [App.Core.Models.ControlPartRecord.Entries#2011389093], was: [App.Core.Models.ControlPartRecord.Entries#2011389093] (initialized)
2023-11-08 21:05:47,987 [49] NHibernate.Engine.IdentifierValue - Default - unsaved-value: 0 // <-- here
NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave.
Type: App.Core.Models.XPTOPartRecord, Entity: App.Core.Models.XPTOPartRecord
at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)
at NHibernate.Type.ManyToOneType.IsDirty(Object old, Object current, Boolean[] checkable, ISessionImplementor session)
at NHibernate.Type.TypeHelper.FindDirty(StandardProperty[] properties, Object[] currentState, Object[] previousState, Boolean[][] includeColumns, Boolean anyUninitializedProperties, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.FindDirty(Object[] currentState, Object[] previousState, Object entity, ISessionImplementor session)
at NHibernate.Event.Default.DefaultFlushEntityEventListener.DirtyCheck(FlushEntityEvent event)
at NHibernate.Event.Default.DefaultFlushEntityEventListener.IsUpdateNecessary(FlushEntityEvent event, Boolean mightBeDirty)
at NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event)
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event)
at NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event)
at NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces)
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results)
at NHibernate.Impl.CriteriaImpl.List(IList results)
at NHibernate.Impl.CriteriaImpl.List[T]()
at Orchard.ContentManagement.DefaultContentQuery.Slice(Int32 skip, Int32 count) in C:\App\src\Orchard\ContentManagement\DefaultContentQuery.cs:line 191
at Orchard.ContentManagement.DefaultContentQuery.ContentQuery`1.Orchard.ContentManagement.IContentQuery<T>.List() in C:\App\src\Orchard\ContentManagement\DefaultContentQuery.cs:line 292
at App.Core.Services.Service.GetData(string val)
at App.Core.Services.Service.Create(List`1 obj)
at App.Api.Controllers.Create(List`1 obj)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
版本: 果园CMS:1.10.x NHibernate:4.0.0.4000 流畅的休眠状态:1.4.0
有人知道如何解决这个问题吗?或者我可以更好地排除为什么会发生这种情况?预先感谢。
解决方案
深入研究 NHibernate 并进行调试后,我发现了我的解决方案的问题。在我的应用程序的特定方法中,我使用 0 值初始化 ParentXTOPartRecord.Id。当我执行刷新时,NHibernate 检测到引用不存在并抛出 TransientObjectException。
修复引用的错误初始化(ParentXPTOPartRecord = null)后,一切正常。因此,解决方法是在我的应用程序的特定方法中修复我的引用初始化。
很可能有一个
XPTOPartRecord
对象通过属性 XPTOPartRecord
引用未保存的 ParentXPTOPartRecord
对象。在保存引用它的对象之前保存新对象,或者将 [CascadeSaveUpdate]
添加到属性 ParentXPTOPartRecord
。