Problem with WHERE in Neo4J, deserialization error - neo4j

I'm using Neo4JClient in .NET Core web application (I created it in VisualStudio version 2019 template) and I had code that works as expected for my example.
I have 3 types of node: Category(important property name - string), Document(important CreatedBy - represents name of User who created it, other properties are used after WHERE), User(important Username - string). Document can have TAG relationship with Category and User can have INTERESTED_IN relationship with Category.
First I created one query to return Document if it have TAG to Category and if User is INTERESTED_IN this Category (Note: I don't have multiple relationships between nodes). Also number of connections with Category is counted so if I have too many Documents method returns only 10 with most connections.
public async Task<IActionResult> GetNewsFeed(string username)
{
string match = $"(a:User{{Username: '{username}'}})-[:INTERESTED_IN]->(res:Category)<-[:TAG]-(b:Document)";
string where = $"NOT(b.isArchived AND c.isArchived AND b.CreatedBy =~ '{username}')";
string with = "b.name AS name, b.CreatedBy AS creator, b.Pictures AS pictures, b.Paragraphs AS paragraphs, COUNT(res) AS interest1";
var result = _context.Cypher.Match(match)
//.Where(where)
.With(with)
.Return((name, creator, pictures, paragraphs, interest1)=> new SimpleNewsFeedDTO {
Name = name.As<string>()
, Creator = creator.As<string>()
, Pictures = pictures.As<string[]>()
, Paragraphs = paragraphs.As<string[]>()
, Interest = interest1.As<int>() })
.OrderBy("interest1 DESC")
.Limit(10)
.ResultsAsync);
return new JsonResult(await result);
}
When I provide correct Username I can see results in right order, but I also want to filter Documents CreatedBy that User (I want to exclude documents created by user), but when I uncomment Where and send request I get following error:
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentException: Neo4j returned a valid response, however Neo4jClient was unable to deserialize into the object structure you supplied.
First, try and review the exception below to work out what broke.
If it's not obvious, you can ask for help at http://stackoverflow.com/questions/tagged/neo4jclient
Include the full text of this exception, including this message, the stack trace, and all of the inner exception details.
Include the full type definition of ExtraBlog.DTOs.SimpleNewsFeedDTO.
Include this raw JSON, with any sensitive values replaced with non-sensitive equivalents:
(Parameter 'content')
---> System.ArgumentNullException: Value cannot be null. (Parameter 'input')
at System.Text.RegularExpressions.Regex.Replace(String input, String replacement)
at Neo4jClient.Serialization.CommonDeserializerMethods.ReplaceAllDateInstancesWithNeoDates(String content)
at Neo4jClient.Serialization.CypherJsonDeserializer`1.Deserialize(String content, Boolean isHttp)
--- End of inner exception stack trace ---
at Neo4jClient.Serialization.CypherJsonDeserializer`1.Deserialize(String content, Boolean isHttp)
at Neo4jClient.GraphClient.Neo4jClient.IRawGraphClient.ExecuteGetCypherResultsAsync[TResult](CypherQuery query)
at ExtraBlog.Controllers.UserController.GetNewsFeed(String username) in E:\GithubRepo\NapredneBaze\Neo4JProject\extra-blog\ExtraBlog\Controllers\UsersController.cs:line 39
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Also when I run something like this in Neo4J browser I get the same result with or without WHERE:
MATCH (a:User{Username: 'NN'})-[:INTERESTED_IN]->(res:Category)<-[t:TAG]-(b:Document)
WHERE (NOT(b.isArchived AND res.isArchived AND b.CreatedBy =~ 'NN'))
WITH b, COUNT(res) AS interest1
RETURN b.name, interest1
ORDER BY interest1 DESC
LIMIT 10
So my question is: why I can't run my method in Visual Studio, and why this query doesn't return what I was expecting?

With these things, it's always good to check what you are generating from the client. To that end you should look at the query.DebugQueryText property. If you do, you'll see the query you would generate would look like this:
MATCH (a:User{Username: 'NN'})-[:INTERESTED_IN]->(res:Category)<-[:TAG]-(b:Document)
WHERE NOT(b.isArchived AND c.isArchived AND b.CreatedBy =~ 'NN')
WITH b.name AS name, b.CreatedBy AS creator, b.Pictures AS pictures, b.Paragraphs AS paragraphs, COUNT(res) AS interest1
RETURN name AS Name, creator AS Creator, pictures AS Pictures, paragraphs AS Paragraphs, interest1 AS Interest
ORDER BY interest1 DESC
LIMIT 10
If you try to execute that in your browser - it won't work, and that's because you use an alias c to access the isArchived property, but there is no c in your MATCH.

Related

Could not load file or assembly 'Oracle.DataAccess, Version=2.112.1.0, Culture=neutral

I am getting this error message while trying to connect to an Oracle 11g Database in Visual Studio 2019 (ASP.NET MVC Core):
BadImageFormatException: Could not load file or assembly
'Oracle.DataAccess, Version=2.112.1.0, Culture=neutral,
PublicKeyToken=89b483f429c47342'. An attempt was made to load a
program with an incorrect format
What i am missing?
I am using:
using Oracle.Database.Client
This is the nuget package:
Oracle.DataAccess.x86 (version: 2.112.1)
I installed Oracle Database 11g Release 2 Client (11.2.0.1.0) for Microsoft Windows (x32)
I have already made sure the app set to run in 32 bit mode in the IIS console. I still can't figure out why is not working.
Can give me a hand?
BadImageFormatException: Could not load file or assembly 'Oracle.DataAccess, Version=2.112.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342'. An attempt was made to load a
> program with an incorrect format
MyApplication.Context.Connection.GetList()
MyApplication.Controllers.ControllerList.Index() in ControllerList.cs
+
List<MyList> myList= dbContext2.GetList().ToList();
lambda_method244(Closure , object , object[] )
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Azure Durable Functions Large Message Support Issue

I am having an issue returning a large list of objects from an activity function to an orchestrator function.
I have a function that downloads a 180 MB file and parses it. This file will produce a list of objects with over 962K entries. Each object has about 70 properties but only about 20% of them are populated.
When I run the function, the code successfully downloads and parses the file into the list, but when the list is returned, an exception is raised with the following information:
Exception: "Exception while executing function: #######"
- Source: "System.Private.CoreLib"
Inner exception: "Error while handling parameter $return after function returned."
- Source: "Microsoft.Azure.WebJobs.Host"
Inner / Inner exception: "Exception of type 'System.OutOfMemoryException' was thrown."
- Source: "System.Private.CoreLib"
The last nested exception lists the NewtonsoftJson package as being the one making the call that generates the out of memory error being reported. I am including the full stack trace for this exception at the end.
I understand that I could possibly serialize the list of objects and store them in an Azure blob entry and then just pick it up again in the next function that needs to process it, but I thought the idea behind durable functions was to avoid all this and maintain a leaner workflow? Also, I based the design on the "Large Message Support #26" github post that states that the durable functions extensions would automatically store the function payload in a blob if the size exceeds the queue message limit (see: https://github.com/Azure/azure-functions-durable-extension/issues/26).
Is there anything I need to do to get this working?
The code is pretty simple:
[FunctionName("GetDataFromSource")]
public static IEnumerable<DataDetail> GetDataFromSource([ActivityTrigger]ISource source, ILogger logger)
{
try
{
string importSettings = Environment.GetEnvironmentVariable(source.SettingsKey);
if (string.IsNullOrWhiteSpace(importSettings))
{
logger.LogError($"No settings key information found for the {source.SourceId} data source"); }
else
{
List<DataDetail> _Data = source.GetVinData().Distinct().ToList();
return vinData;
}
}
catch (Exception ex)
{
logger.LogCritical($"Error processing the {source.SourceId} Vin data source. *** Exception: {ex}");
}
return new List<DataDetail>();
}
This is the stack trace for the most inner exception:
at System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)
at System.Text.StringBuilder.Append(Char value, Int32 repeatCount)
at System.Text.StringBuilder.Append(Char value)
at System.IO.StringWriter.Write(Char value)
at Newtonsoft.Json.JsonTextWriter.WritePropertyName(String name, Boolean escape)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)
at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)
at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)
at DurableTask.Core.Serializing.JsonDataConverter.Serialize(Object value, Boolean formatted)
at Microsoft.Azure.WebJobs.Extensions.DurableTask.MessagePayloadDataConverter.Serialize(Object value, Int32 maxSizeInKB) in C:\projects\azure-functions-durable-extension\src\WebJobs.Extensions.DurableTask\MessagePayloadDataConverter.cs:line 55
at Microsoft.Azure.WebJobs.Extensions.DurableTask.MessagePayloadDataConverter.Serialize(Object value) in C:\projects\azure-functions-durable-extension\src\WebJobs.Extensions.DurableTask\MessagePayloadDataConverter.cs:line 43
at Microsoft.Azure.WebJobs.DurableActivityContext.SetOutput(Object output) in C:\projects\azure-functions-durable-extension\src\WebJobs.Extensions.DurableTask\DurableActivityContext.cs:line 136
at Microsoft.Azure.WebJobs.Extensions.DurableTask.ActivityTriggerAttributeBindingProvider.ActivityTriggerBinding.ActivityTriggerReturnValueBinder.SetValueAsync(Object value, CancellationToken cancellationToken) in C:\projects\azure-functions-durable-extension\src\WebJobs.Extensions.DurableTask\Bindings\ActivityTriggerAttributeBindingProvider.cs:line 213
at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.ProcessOutputParameters(CancellationToken cancellationToken) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 972
I came across a similar issue when working with Durable Functions.
There are a couple of solutions / workarounds to this:
As you say, you could store the function payload in blob storage and retrieve them when you require. This works but there is a performance hit and can take a while to retrieve depending on how big your file is.
The other option would be to batch your calls. I'm not entirely sure what your GetVinData() method does but you could modify this so you only retrieve 50,000 (or x number) items at a time. Your orchestrator could call your activity function multiple times and build up your list in the orchestrator.
[FunctionName(nameof(OrchestratorAsync))]
public async Task OrchestratorAsync([OrchestrationTrigger] IDurableOrchestrationContext context)
{
var dataDetailList = new List<DataDetail>();
var batches = BuildBatchesHere();
foreach (var batch in batches)
{
dataDetailList.AddRange(
await context.CallActivityAsync<List<DataDetail>>(
nameof(GetDataFromSource), batch);
}
// Do whatever you need with dataDetailList
}
The Durable Functions extension will automatically take care of storing large messages in blobs when they don't fit in queues and tables. However, this support assumes that enough memory is available to serialize the payloads so that they can be uploaded to blob. Unfortunately, the design of the Durable Task Framework requires serializing the payload into a string first before uploading to blob, which means there will be a lot of memory pressure.
There are a few things you can try to mitigate this problem:
Make sure your function app is running in 64-bit mode. By default, Function apps are created in 32-bit mode, which has lower memory limits. We've seen several cases where simply switching to 64-bit resolves out-of-memory issues.
Try increasing the memory limit for your particular plan. If you're running in the Azure Functions Consumption plan, maximum memory is fixed. However, if you're running in Elastic Premium or App Service Plans, you have the option of using larger VMs with more memory.
As #stephyness suggested, consider limiting the amount of data your return from your function. This could be returning a subset of the full list or it could be the full list but with smaller payloads (for example, source.GetVinData().Distinct().Select(x => x.VinNumber) (you might even get better results by simply removing .ToList(), which may be creating an unnecessary copy of your data). Essentially, return only the data that the orchestrator absolutely needs to make progress. Returning data the orchestrator doesn't need is unnecessary overhead.
Also be aware that there's a non-trivial performance impact when large message support is used. If you can avoid relying on it, your orchestrations will run much faster.
Other tips for controlling memory usage can be found in the Performance and Scale documentation.

How can I filter by more than one user pattern in TFS API?

I have the following code:
var tfs = new TfsTeamProjectCollection(new Uri(TFS_SERVER_URL));
tfs.EnsureAuthenticated();
var query = GetQuery(...)
var identities = ims.ReadFilteredIdentities(query, 5000, null, true, (int)MembershipQuery.None);
foreach (var item in identities.Items)
{
Console.WriteLine("{0,-20} {1,-20} {2}", item.DisplayName, item.UniqueName, item.GetAttribute("Mail", null));
}
Now, when query is something like
Microsoft.TeamFoundation.Identity.Type == 'User' AND (Microsoft.TeamFoundation.Identity.DisplayName CONTAINS 'alice' OR Microsoft.TeamFoundation.Identity.DisplayName CONTAINS 'bob')
The code throws the following exception:
Microsoft.TeamFoundation.Framework.Client.IdentityExpressionException: TF400819: Query Expression is not well-formed
---> System.Web.Services.Protocols.SoapException: TF400819: Query Expression is not well-formed
--- End of inner exception stack trace ---
at Microsoft.TeamFoundation.Client.Channels.TfsHttpClientBase.HandleReply(TfsClientOperation operation, TfsMessage message, Object[]& outputs)
at Microsoft.TeamFoundation.Client.Channels.TfsHttpClientBase.Invoke(TfsClientOperation operation, Object[] parameters, TimeSpan timeout, Object[]& outputs)
at Microsoft.TeamFoundation.Framework.Client.IdentityManagementWebService2.ReadFilteredIdentities(String expression, Int32 suggestedPageSize, String lastSearchResult, Boolean lo
okForward, Int32 queryMembership, Int32 features)
at Microsoft.TeamFoundation.Framework.Client.IdentityManagementService2.ReadFilteredIdentities(String expression, Int32 suggestedPageSize, String lastSearchResult, Boolean lookF
orward, Int32 queryMembership)
at TFSTool.Program.GetUsers(IEnumerable`1 args) in C:\dayforce\SharpTop\Build\ConfigurationManagement\utilities\tfstool\Program.cs:line 1621
at TFSTool.Program.Main(String[] args) in C:\dayforce\SharpTop\Build\ConfigurationManagement\utilities\tfstool\Program.cs:line 519
However, if I search by just one user pattern, for example:
Microsoft.TeamFoundation.Identity.Type == 'User' AND Microsoft.TeamFoundation.Identity.DisplayName CONTAINS 'mark'
It works just fine.
So, my question - is it possible to search by more than one user pattern in TFS Api or am I forced to repeat the query for each pattern separately?
No, you can't. "OR" operator is not supported by the query expression. Refer to the description for ReadFilteredIdentities() method in this article for details: TeamFoundationIdentityService Class.
ReadFilteredIdentities is used to retrieve a set of identities based
on an expression. The expression is a syntax that resembles a SQL
WHERE clause. For details about the expressions capabilities, see the
documentation of the QueryExpression class. There are two parts to the
expression. There are a set of values that can be used from the
identity and they must be AND'ed together.

Why EFContextProvider 1.4.16 throws DbUpdateConcurrencyException when trying to update Enum value?

I'm trying to save a single change - an enum property value update. EFContextProvider.SaveChanges() is called on the server, but generated SQL is wrong and when executed by the EFContextProvider it throws System.Data.Entity.Infrastructure.DbUpdateConcurrencyException.
The enum property is defined like this:
public virtual System.Nullable<StanZleceniaOplaty> Stan { get; set; }
public enum StanZleceniaOplaty : int
{
Created,
Started,
Canceled,
Rejected,
Paid
}
EntityTypeConfiguration for entity ZlecenieOplaty configures Stan with the following code:
this
.Property(p => p.Stan)
.IsConcurrencyToken()
.HasColumnType("int");
Please note that this enum property IsConcurrencyToken.
I'm changing the enum from Created to Canceled and calling SaveChanges().
I can see that the SQL generated by EFContextProvider agains the EF 6.1 DB is wrong ([Stan] is not changed, because #0 == #2, #2 has wrong value - should be 0).
exec sp_executesql N'UPDATE [dbo].[ZlecenieOplaty]
SET [Stan] = #0
WHERE (([Id] = #1) AND ([Stan] = #2))
SELECT [NrZlecenia]
FROM [dbo].[ZlecenieOplaty]
WHERE ##ROWCOUNT > 0 AND [Id] = #1',
N'#0 int,#1 int,#2 int',
#0=2,
#1=3,
#2=2
In effect the following exception is thrown.
System.Data.Entity.Infrastructure.DbUpdateConcurrencyException occurred
HResult=-2146233087
Message=Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Internal.InternalContext.SaveChanges()
at Alcance.Entities.AlcanceDbContext.SaveChanges() in d:\Develop\alcance\src\dev\Alcance.Data\Model\AlcanceModel.AlcanceDbContext.Connection.cs:line 121
InnerException: System.Data.Entity.Core.OptimisticConcurrencyException
HResult=-2146233087
Message=Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Source=EntityFramework
StackTrace:
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected, UpdateCommand source)
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction)
at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction)
at System.Data.Entity.Internal.InternalContext.SaveChanges()
InnerException:
I opened https://github.com/Breeze/breeze.server.net/issues/8.
Can anybody confirm that this is a bug?

Spring.Objects.Factory.ObjectCreationException: System.ArgumentNullException: Key cannot be null

This is a long shot...
I'm using spring 1.3.2 and at random times I get ArgumentNullException exception (See stack trace below).
I'm configuring the container in a mix between XML and Code (by using ObjectDefinitionBuilder directly, no code config). And the registrations take place in parallel (5 threads loading definitions).
All my objects use Autowiring via Constructor, the error happens in both components that have items in the constructor or not.
I'm doing the following call after everything was registered in the container
context.GetObjectsOfType(typeof (IFoo)).OfType<DictionaryEntry>().Select(d => (IFoo) d.Value)
From the stack trace and looking at the code, I see that the call to IsAlias seems to be failing, but not sure I understand how this can happen.
Any thoughts/Ideas?
Stack Trace:
Spring.Objects.Factory.ObjectCreationException: Error creating object with name 'My.App.SomeFooImplementation' : Initialization of object failed : Key cannot be null.
Parameter name: key ---> System.ArgumentNullException: Key cannot be null.
Parameter name: key
at System.Collections.Hashtable.ContainsKey(Object key)
at System.Collections.Specialized.OrderedDictionary.Contains(Object key)
at Spring.Objects.Factory.Support.AbstractObjectFactory.IsAlias(String name)
at Spring.Objects.Factory.Support.DefaultListableObjectFactory.DoGetObjectNamesForType(Type type, Boolean includeNonSingletons, Boolean allowEagerInit)
at Spring.Objects.Factory.Support.DefaultListableObjectFactory.GetObjectNamesForType(Type type, Boolean includePrototypes, Boolean includeFactoryObjects)
at Spring.Objects.Factory.ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(IListableObjectFactory factory, Type type, Boolean includePrototypes, Boolean includeFactoryObjects)
at Spring.Objects.Factory.Support.DefaultListableObjectFactory.FindAutowireCandidates(String objectName, Type requiredType, DependencyDescriptor descriptor)
at Spring.Objects.Factory.Support.DefaultListableObjectFactory.ResolveDependency(DependencyDescriptor descriptor, String objectName, IList autowiredObjectNames)
at Spring.Objects.Factory.Support.ConstructorResolver.CreateArgumentArray(String objectName, RootObjectDefinition rod, ConstructorArgumentValues resolvedValues, ObjectWrapper wrapper, Type[] paramTypes, MethodBase methodOrCtorInfo, Boolean autowiring, UnsatisfiedDependencyExceptionData& unsatisfiedDependencyExceptionData)
at Spring.Objects.Factory.Support.ConstructorResolver.AutowireConstructor(String objectName, RootObjectDefinition rod, ConstructorInfo[] chosenCtors, Object[] explicitArgs)
at Spring.Objects.Factory.Support.AbstractAutowireCapableObjectFactory.CreateObjectInstance(String objectName, RootObjectDefinition objectDefinition, Object[] arguments)
at Spring.Objects.Factory.Support.AbstractAutowireCapableObjectFactory.InstantiateObject(String name, RootObjectDefinition definition, Object[] arguments, Boolean allowEagerCaching, Boolean suppressConfigure)
--- End of inner exception stack trace ---
at Spring.Objects.Factory.Support.AbstractAutowireCapableObjectFactory.InstantiateObject(String name, RootObjectDefinition definition, Object[] arguments, Boolean allowEagerCaching, Boolean suppressConfigure)
at Spring.Objects.Factory.Support.AbstractObjectFactory.CreateAndCacheSingletonInstance(String objectName, RootObjectDefinition objectDefinition, Object[] arguments)
at Spring.Objects.Factory.Support.AbstractObjectFactory.GetObjectInternal(String name, Type requiredType, Object[] arguments, Boolean suppressConfigure)
at Spring.Objects.Factory.Support.AbstractObjectFactory.GetObject(String name)
Edit:
I just got all the definition names and somehow there is a null entry in there, that seems to be the issue, not sure why it is happening yet...
The only fix I could come up with was to change the internal objectDefinitionNames ArrayList to be wrapped with ArrayList.Synchronized with reflection. Not nice at all but seems to do the job.
var field = factory.GetType().GetField("objectDefinitionNames", BindingFlags.NonPublic | BindingFlags.Instance);
if (field == null)
throw new InvalidOperationException("Could not get Definitions field from application context.");
var value = (ArrayList) field.GetValue(factory);
field.SetValue(factory, ArrayList.Synchronized(value));

Resources