OrchardCMS / Orchard

Orchard is a free, open source, community-focused Content Management System built on the ASP.NET MVC platform.
https://orchardproject.net
BSD 3-Clause "New" or "Revised" License
2.37k stars 1.12k forks source link

IdentifierGenerationException when Workflow starts with the content created event #3856

Open orchardbot opened 11 years ago

orchardbot commented 11 years ago

@Piedone created: https://orchard.codeplex.com/workitem/20028

Set the content created event as the starting point of the wf and let the content type be comment. (What is chained to the event is irrelevant.) Write a comment.

The following exception occurs and is thrown from WorkflowManager ln 55:

NHibernate.Id.IdentifierGenerationException occurred HResult=-2146232832 Message=attempted to assign id from null one-to-one property: ContentItemRecord Source=NHibernate StackTrace: at NHibernate.Id.ForeignGenerator.Generate(ISessionImplementor sessionImplementor, Object obj) at NHibernate.Event.Default.AbstractSaveEventListener.SaveWithGeneratedId(Object entity, String entityName, Object anything, IEventSource source, Boolean requiresImmediateIdAccess) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.SaveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.EntityIsTransient(SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.PerformSaveOrUpdate(SaveOrUpdateEvent event) at NHibernate.Event.Default.DefaultSaveOrUpdateEventListener.OnSaveOrUpdate(SaveOrUpdateEvent event) at NHibernate.Impl.SessionImpl.FireSaveOrUpdate(SaveOrUpdateEvent event) at NHibernate.Impl.SessionImpl.SaveOrUpdate(String entityName, Object obj) at NHibernate.Engine.CascadingAction.SaveUpdateCascadingAction.Cascade(IEventSource session, Object child, String entityName, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeToOne(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeAssociation(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeProperty(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeCollectionElements(Object parent, Object child, CollectionType collectionType, CascadeStyle style, IType elemType, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeCollection(Object parent, Object child, CascadeStyle style, Object anything, CollectionType type) at NHibernate.Engine.Cascade.CascadeAssociation(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeProperty(Object parent, Object child, IType type, CascadeStyle style, Object anything, Boolean isCascadeDeleteEnabled) at NHibernate.Engine.Cascade.CascadeOn(IEntityPersister persister, Object parent, Object anything) at NHibernate.Event.Default.AbstractFlushingEventListener.CascadeOnFlush(IEventSource session, IEntityPersister persister, Object key, Object anything) at NHibernate.Event.Default.AbstractFlushingEventListener.PrepareEntityFlushes(IEventSource session) at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) at NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event) at NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet1 querySpaces) at NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) at NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters) at NHibernate.Impl.ExpressionQueryImpl.List() at NHibernate.Linq.DefaultQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery) at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression) at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression) at Remotion.Linq.QueryableBase1.GetEnumerator() at System.Collections.Generic.List1.InsertRange(Int32 index, IEnumerable1 collection) at System.Collections.Generic.List1.AddRange(IEnumerable1 collection) at Orchard.Workflows.Services.WorkflowManager.TriggerEvent(String name, IContent target, Func`1 tokensContext)

InnerException:

Piedone commented 4 years ago

Reviving this OMG so old issue... We've just seen this happening a lot due to comment spam: spambot would POST a comment, which is then rejected as it should, but in the meantime, deep somewhere in the Comment content item's handlers we'll get such an exception. The exception will come from some content query or IContentManager.Get() call somewhere, but in any case some read content item operation.

My hunch is that this is (and only happening because) CommentPartDriver is somewhat unique in that it creates a content item-content item relationship in the driver:

part.CommentedOnContainer = commentedOn.Container.ContentItem.Id;

I didn't really dive deeper into this.

A completely hackish solution is to put this into CommentController.Create():

// Dummy calls. Otherwise we'd get NHibernate.Id.IdentifierGenerationExceptions ("attempted to assign id 
// from null one-to-one property: ContentItemRecord") when updating the Comment content item.
// Also see: https://github.com/OrchardCMS/Orchard/issues/3856
var page = Services.ContentManager.New("Dummy");
var pageShape = Services.ContentManager.UpdateEditor(page, this);
// Dummy check just so the above calls won't get optimized out by the compiler.
if (pageShape == null) return null;
Piedone commented 4 years ago

Also, republishing the content item the comment is under solves the issue.