Widget can not be saved

Topics: Troubleshooting, Writing modules
Apr 20, 2012 at 9:20 PM

Hi guys,

I'm writing a very simple widget which is used to display a button at different location. However, I received this error in the log:

 

NHibernate.Impl.AbstractSessionImpl - DTC transaction prepre phase failed
NHibernate.Exceptions.GenericADOException: could not insert: [Koneka.Feedback.Models.FeedbackWidgetPartRecord#15][SQL: INSERT INTO Koneka_Feedback_FeedbackWidgetPartRecord (Top, Right, Bottom, Left, Id) VALUES (?, ?, ?, ?, ?)] ---> System.Data.SqlServerCe.SqlCeException: There was an error parsing the query. [ Token line number = 1,Token line offset = 55,Token in error = Top ]
   at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr)
   at System.Data.SqlServerCe.SqlCeCommand.CompileQueryPlan()
   at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
   at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery()
   at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
   at NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation expectation)
   at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session)
   --- End of inner exception stack trace ---
   at NHibernate.Persister.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.ExecuteActions(IList list)
   at NHibernate.Engine.ActionQueue.ExecuteActions()
   at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session)
   at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event)
   at NHibernate.Impl.SessionImpl.Flush()
   at NHibernate.Transaction.AdoNetWithDistrubtedTransactionFactory.DistributedTransactionContext.System.Transactions.IEnlistmentNotification.Prepare(PreparingEnlistment preparingEnlistment)

 

However, on the front end, Orchard sends a success notification that the Widget has been successfully generated. The widget which was created not shown in the list due to the error in the log.

I try to understand why I run into this issue. Here is the code which I used to write the widget:

FeedbackWidgetPartRecord.cs

 

using Orchard;
using Orchard.ContentManagement.Records;
using Orchard.Environment.Extensions;

namespace Koneka.Feedback.Models {
    public class FeedbackWidgetPartRecord : ContentPartRecord {
        public virtual string Top{ get; set; }
        public virtual string Right{ get; set; }
        public virtual string Bottom{ get; set; }
        public virtual string Left{ get; set; }

    }
}

 

FeedbackWidgetPart.cs

 

using Orchard;
using Orchard.ContentManagement;
using Orchard.Environment.Extensions;

namespace Koneka.Feedback.Models {
    public class FeedbackWidgetPart : ContentPart<FeedbackWidgetPartRecord> {
        public string Top {
            get { return Record.Top; }
            set { Record.Top = value; }
        }
        public string Right {
            get { return Record.Right; }
            set { Record.Right = value; }
        }
        public string Bottom {
            get { return Record.Bottom; }
            set { Record.Bottom = value; }
        }
        public string Left {
            get { return Record.Left; }
            set { Record.Left = value; }
        }

    }
}

 

FeedbackWidgetPartHandler.cs

 

using JetBrains.Annotations;
using Orchard.ContentManagement.Handlers;
using Orchard.Data;
using Orchard.Environment.Extensions;
using Koneka.Feedback.Models;

namespace Koneka.Feedback.Handlers
{
    public class FeedbackWidgetPartHandler : ContentHandler
    {
        public FeedbackWidgetPartHandler(IRepository<FeedbackWidgetPartRecord> repository)
        {
            Filters.Add(StorageFilter.For(repository));
        }
    }
}

 

FeedbackWidgetPartDriver.cs

 

using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Drivers;
using Orchard.Localization;
using Orchard.UI.Notify;
using Orchard.Environment.Extensions;
using Koneka.Feedback.Models;

namespace Koneka.Feedback.Drivers
{
    public class FeedbackWidgetPartDriver : ContentPartDriver<FeedbackWidgetPart>
    {
        private readonly INotifier _notifier;
        private const string TemplateName = "Parts/KonekaFeedbackWidget";

        public Localizer T { get; set; }

        public FeedbackWidgetPartDriver(INotifier notifier)
        {
            _notifier = notifier;
            T = NullLocalizer.Instance;
        }

        protected override DriverResult Display(FeedbackWidgetPart part, string displayType, dynamic shapeHelper)
        {
            return ContentShape("Parts_KonekaFeedbackWidget",
                () => shapeHelper.Parts_KonekaFeedbackWidget(ContentItem: part));
        }

        protected override DriverResult Editor(FeedbackWidgetPart part, dynamic shapeHelper)
        {
            return ContentShape("Parts_KonekaFeedbackWidget",
                    () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: part, Prefix: Prefix));
        }

        protected override DriverResult Editor(FeedbackWidgetPart part, IUpdateModel updater, dynamic shapeHelper)
        {
            if (!updater.TryUpdateModel(part, Prefix, null, null))
            {
                _notifier.Error(T("Error during FeedbackWidgetPart update!"));
            }
            return Editor(part, shapeHelper);
        }

    }
}

 

Migration.cs

 

using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents.Extensions;
using Orchard.Data.Migration;
using Orchard.Core.Containers.Models;

using Orchard.Comments.Models;
using Orchard.Core.Common.Models;
using Orchard.Widgets.Models;
using Koneka.Feedback.Models;
using Orchard.Environment.Extensions;

namespace Koneka.Feedback
{
    public class Migrations : DataMigrationImpl
    {
        public int Create()
        {

            SchemaBuilder.CreateTable("FeedbackWidgetPartRecord", table => table
                .ContentPartRecord()
                .Column<string>("Top", column => column.WithDefault("auto"))
                .Column<string>("Right", column => column.WithDefault("auto"))
                .Column<string>("Bottom", column => column.WithDefault("auto"))
                .Column<string>("Left", column => column.WithDefault("auto")));

ContentDefinitionManager.AlterPartDefinition(typeof(FeedbackWidgetPart).Name, part => part.Attachable());

            ContentDefinitionManager.AlterTypeDefinition("FeedbackWidget", type => type
                .WithPart("FeedbackWidgetPart")
                .WithPart("WidgetPart")
                .WithPart("CommonPart")
                .WithSetting("Stereotype", "Widget"));

            return 1;
            
        }
    }
}

 

 

The Views are in correct folders. The Views are displayed just fine. I also run debugging in VS. It shows the data of the FeedbackWidgetPart are loaded properly after updater.TryUpdateModel

updater.TryUpdateModel(part, Prefix, null, null)

Anyone knows what happens? Thanks in advance

Coordinator
Apr 20, 2012 at 11:14 PM

My guess would be that you modified the record structure and migration, assuming it the database would follow. I'd bet your database structure and code are out of sync.

Apr 20, 2012 at 11:17 PM
bertrandleroy wrote:

My guess would be that you modified the record structure and migration, assuming it the database would follow. I'd bet your database structure and code are out of sync.

I have remove the mappings.bin and force Orchard to regenerate that file. It still does not work. I have even re-install the application. 

Coordinator
Apr 20, 2012 at 11:27 PM

It won't work if your database still has the old schema.

Apr 20, 2012 at 11:44 PM
bertrandleroy wrote:

It won't work if your database still has the old schema.

I check the table Koneka_Feedback_FeedbackWidgetPartRecord. The schema is exactly the same as the one I have in the code. I checked everything I could. Don't know what is going on. What is your suggestion for the solution?

Coordinator
Apr 20, 2012 at 11:48 PM

It was just a guess based on the symptoms. Your code looks fine to me.

Coordinator
Apr 20, 2012 at 11:49 PM

Oh! I get it. Top is a reserved SQL word. You can't use that name. I think you can tell the system to use another name in the DB from the migration.

Apr 21, 2012 at 5:36 PM
bertrandleroy wrote:

Oh! I get it. Top is a reserved SQL word. You can't use that name. I think you can tell the system to use another name in the DB from the migration.

That was brilliant. Thanks so much.