I've hit a little snag with UD_Tables, and I'm not sure the best way to recover.
I'm in a prototype database for a rather large client (implementation in progress). Early in the design, we added a number of UD tables with the fields they wanted. In addition to the standard business objects (e.g. CsName_Demo), we created a couple of custom ones.
As the prototype evolved, we discovered some of the fields weren't needed anymore. Our normal MO for removing fields (bad habit, I know) is to remove them from Define Tables, then touch all the windows based on those tables, which cleans up the orphaned fields. This time, we got a PK violation on UD_WindowFields. Apparently, iMIS now only deletes rows from UD_WindowFields if they exist in UD_Field. I cleaned up the orphaned fields through SQL and the windows worked OK. That problem is solved, and desktop iMIS is (mostly) happy.
The big problem started when I applied the 15.1.1.3632 upgrade. I got multiple errors on the business objects where fields were removed. iSA > "Auto-Generate Business Objects from User-Defined Tables" > Build All dies after several minutes with "Server Application Unavailable", and Asi.Webroot.Log shows the error below. BOD won't open at all, giving a very similar error, and highlighting a line of code that reads "DataBind();".
I can't be positive this is a problem with the patch -- the problem is happening in a VM, and a full BuildPublishBOs dies with a "permissions" error (but it's really out of disk space). I'll submit that as an SMR separately.
My main questions:
- What's the best way to recover from this?
- I think I found the orphan references in DocumentMain.Blob, but I haven't read the code very closely or figured out how hard it will be to change it.
- Is adding the fields back through Customizer the fastest way, or are newly-assigned GUIDs likely to thwart my effort?
- Could manually creating the vBoCsName_Demo views with the "missing" fields get me over the hump?
- Would the asi_DeleteDocument procedure clear out the bad history of the UD-based-BO and force it to start fresh?
- How can I take an inventory of objects which depend on my Customizer tables, so I clean them up in the first place? More generally, how can I find all BOs that refer to a particular field in a table or view?
- This problem is with the BO, but I suspect fixing this level could cause a new problem with any Query refering to that BO property. How can I inventory which IQA queries refer to a given BO, or a particular property within that BO?
This could continue ad nauseum, I'm sure, but I think it's probably impractical to e.g. find every module or setting where the Key of a given Query is stored. Hopefully at some level there will be enough resilience to return a useful error message rather than an exception.
Error from iSA -> rebuild
2009-10-05 06:45:26.642 ERROR 2404 Asi.Webroot - Unexpected website error: Exception of type 'System.Web.HttpUnhandledException' was thrown.
Exception: System.Web.HttpUnhandledException
Message: Exception of type 'System.Web.HttpUnhandledException' was thrown.
Source: System.Web
at System.Web.UI.Page.HandleError(Exception e)
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
at System.Web.UI.Page.ProcessRequest()
at System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext context)
at System.Web.UI.Page.ProcessRequest(HttpContext context)
at ASP.asicommon_controls_bsa_objectbrowser_aspx.ProcessRequest(HttpContext context) in c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\rmhcdev\b50c3816\b7957e61\App_Web_hhjlke27.1.cs:line 0
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Nested Exception
Exception: System.MissingMethodException
Message: Method not found: 'Void Asi.Web.UI.Common.BSA.ObjectBrowserHelper.GetDocumentHierarchyList2(System.Guid, Boolean, System.String, System.String, System.Collections.Generic.IList`1ByRef, System.Collections.Generic.IList`1ByRef)'.
Source: Asi.Webroot.AsiCommon.Controls.BSA
at Asi.Web.UI.Common.BSA.ObjectBrowser.SelectNode(Guid hierarchyKey)
at Asi.Web.UI.Common.BSA.ObjectBrowser.AddressGo(Guid hierarchyKey)
at Asi.Web.UI.Common.BSA.ObjectBrowser.InitTreeView()
at Asi.Web.UI.Common.BSA.ObjectBrowser.DataBind()
at System.Web.UI.Control.DataBindChildren()
at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
at System.Web.UI.Control.DataBind()
at System.Web.UI.Control.DataBindChildren()
at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
at System.Web.UI.Control.DataBind()
at System.Web.UI.Control.DataBindChildren()
at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
at System.Web.UI.Control.DataBind()
at System.Web.UI.Control.DataBindChildren()
at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
at System.Web.UI.Control.DataBind()
at System.Web.UI.Control.DataBindChildren()
at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
at System.Web.UI.Control.DataBind()
at ASP.asicommon_controls_bsa_objectbrowser_aspx.OnLoad(EventArgs e) in c:\Program Files\ASI\iMIS15\Net\AsiCommon\Controls\BSA\ObjectBrowser.aspx:line 98
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Edit: second block of code was meant to be the BOD error, but it didn't copy/paste out of my VM correctly. I can get that one later if it's helpful.
If you have not customized
If you have not customized the autogenerated BOD objects at all, then yes, deleting and recreating them is probably the easiest method. You can do this via the UI (recycle them, then go to iSA > Utilities > Document System, find them in the Recycle Bin, and use Organize > Purge to get rid of them) or via asi_DocumentDelete.
For #2, every BO generates a view; you could check the generated view's dependencies to see what tables/columns/views it depends on. (There are some more opaque references, such as if you use a Property Query or a Property References BO, but in general that will get you pretty far.)
For #3, there isn't a good way to do it as far as I know. The easiest way to do it would probably be a utility written in C#; we have something along those lines we use to update IQA queries when we rename a BO or a BO property that might work for that situation (it doesn't detect other BOs that depend on a BO or property, only IQA queries). Note that IQA queries reference BOs and properties by name, not by GUID, so deleting and recreating the BOD object shouldn't cause any problems. If it does, let me know and I'll get you a copy of the utility.
Also, that iSA -> rebuild error is... odd. MissingMethodException is usually thrown when you have a version mismatch between one assembly and another; for example, the UI code and the assembly were updated in sync (in such a way that the method signature for that call changed), but you only got the UI updates. If this is the latest patch, make sure to report it to TS so we can get the additional updated file out.