- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Fast Serialization exception
Joined: 30-Jun-2005
Version 2.5, Adapter
I am trying to serialize a simple, empty EntityCollection(of FolderRelation) and I get this exception on Deserialization:
System.ThrowHelper.ThrowArgumentOutOfRangeException(argument As ExceptionArgument, resource As ExceptionResource)
CODA GUI.EXE: N 00062
System.ThrowHelper.ThrowArgumentOutOfRangeException()
CODA GUI.EXE: N 00012
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadTokenizedString(bucket As Int32)
CODA GUI.EXE: N 00064
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadOptimizedString()
CODA GUI.EXE: N 00027
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.ReadEntityMemberCollections(entity As EntityBase2)
CODA GUI.EXE: N 00159
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.ReadReferencedEntities(rootEntity As EntityBase2)
CODA GUI.EXE: N 00447
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.Deserialize(collection As IFastSerializableEntityCollection2)
CODA GUI.EXE: N 00052
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.Deserialize(serializedData As Byte[], root As Object)
CODA GUI.EXE: N 00105
SD.LLBLGen.Pro.ORMSupportClasses.SerializationHelper.Deserialize(entityCollection As IEntityCollection2, info As SerializationInfo, context As StreamingContext)
CODA GUI.EXE: N 00039
SD.LLBLGen.Pro.ORMSupportClasses.EntityCollectionBase2`1..ctor(info As SerializationInfo, context As StreamingContext)
CODA GUI.EXE: N 00191
Coda.Entities.HelperClasses.EntityCollection`1..ctor(info As SerializationInfo, context As StreamingContext)
EntityCollection.vb: line 0116, col 04, IL 0001
What is really strange is the FastDeserializer.ReadEntityMemberCollections is running at all, as there were no entities in the collection to begin with.
EDIT: I realized this was not an empty collection. It was a collection that had been fetched from the database, and is deserializing while remoting back to the client machine.
The prefetch path that fetches this collection is:
Dim prefetchPath As IPrefetchPath2 = New PrefetchPath2(CInt(EntityType.FolderRelationEntity))
Dim foldersElement As IPrefetchPathElement2 = prefetchPath.Add(FolderRelationEntity.PrefetchPathFolder)
FolderRelation has a M:1 relationship with Folder. So FolderRelation (M:1) Folder
When I remove the PrefetchPathElement that goes to 'Folder' there is no problem with the serialization.
Joined: 30-Jun-2005
I've retested the fast serialization with all kinds of different object graphs (Entity based and EntityCollection based), and they all give errors on the Deserialization. The exceptions are usually "InvalidCastException."
I don't know what I could be doing wrong here. I have identical DLLs on the client and server side, use Binary formatting, have set the SerializationHelper.Optimization = Fast on both sides, and am not doing any serialization of custom properties.
Here's what happens when I try to fetch a single entity with a 1:N relationship in its prefetchpath across a remoting boundary (using binary formatting):
TargetInvocationException: {"Unable to read beyond the end of the stream."}
at System.RuntimeMethodHandle._SerializationInvoke(Object target, SignatureStruct& declaringTypeSig, SerializationInfo info, StreamingContext context)
at System.RuntimeMethodHandle.SerializationInvoke(Object target, SignatureStruct declaringTypeSig, SerializationInfo info, StreamingContext context)
at System.Reflection.RuntimeConstructorInfo.SerializationInvoke(Object target, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.CompleteISerializableObject(Object obj, SerializationInfo info, StreamingContext context)
at System.Runtime.Serialization.ObjectManager.FixupSpecialObject(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Remoting.Channels.CoreChannel.DeserializeBinaryResponseMessage(Stream inputStream, IMethodCallMessage reqMsg, Boolean bStrictBinding)
at System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at CODA.DataAccessGateway.DataAccessGateway.FetchEntity(IEntity2& entity, PrefetchPath2 prefetchPath)
at Coda.BusinessServicesProviders.EntityManagers.EntityManagerBase.FetchEntity(CommonEntityBase& entity, PrefetchPath2 prefetchPath) in C:\Projects\CODA\41\Source\BusinessServicesProviders\EntityManagers\EntityManagerBase.vb:line 41
This happens whether or not I use a normal BinaryFormatter to do the Serialize/Deserialize or use the remoting system...
Here's some code:
Dim myEntity as New EmployeeEntity("0885")
myEntity.EmployeeBonus.AddNew
Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim stream As New System.IO.MemoryStream
formatter.Serialize(stream, myEntity)
stream.Position = 0
Dim myobject As Object = formatter.Deserialize(stream)
BLAM! System.IO.EndOfStreamException
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadOptimizedInt32()
CODA GUI.EXE: N 00016
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadTokenizedString(bucket As Int32)
CODA GUI.EXE: N 00013
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadOptimizedString()
CODA GUI.EXE: N 00027
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.ReadEntityMemberCollections(entity As EntityBase2)
CODA GUI.EXE: N 00159
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.ReadReferencedEntities(rootEntity As EntityBase2)
CODA GUI.EXE: N 00447
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.Deserialize(entity As EntityBase2)
CODA GUI.EXE: N 00044
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.Deserialize(serializedData As Byte[], root As Object)
CODA GUI.EXE: N 00148
SD.LLBLGen.Pro.ORMSupportClasses.SerializationHelper.Deserialize(entity As EntityBase2, info As SerializationInfo, context As StreamingContext)
CODA GUI.EXE: N 00039
SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2..ctor(info As SerializationInfo, context As StreamingContext)
CODA GUI.EXE: N 01180
Coda.Entities.EntityClasses.CommonEntityBase..ctor(info As SerializationInfo, context As StreamingContext)
CommonEntityBase.vb: line 0054, col 04, IL 0001
Coda.Entities.EntityClasses.EmployeeEntity..ctor(info As SerializationInfo, context As StreamingContext)
EmployeeEntity.vb: line 0283, col 04, IL 0001
Dim myEntity as New EmployeeEntity("0885") myEntity.EmployeeBonus.AddNew Dim formatter As New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter Dim stream As New System.IO.MemoryStream formatter.Serialize(stream, myEntity) stream.Position = 0 Dim myobject As Object = formatter.Deserialize(stream)
And if you seek back to the beginning of the stream? Example:
[Test]
public void SerializationWithMNRelationFastTest()
{
EntityCollection<CustomerEntity> customers = new EntityCollection<CustomerEntity>();
PrefetchPath2 path = new PrefetchPath2(EntityType.CustomerEntity);
path.Add(CustomerEntity.PrefetchPathEmployees);
using(DataAccessAdapter adapter = new DataAccessAdapter())
{
adapter.FetchEntityCollection(customers, new RelationPredicateBucket(CustomerFields.Country == "Germany"), path);
}
Assert.AreEqual(11, customers.Count);
foreach(CustomerEntity customer in customers)
{
Assert.IsTrue(customer.Employees.Count > 0);
}
SerializationHelper.Optimization = SerializationOptimization.Fast;
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
formatter.Serialize(stream, customers);
stream.Seek(0, SeekOrigin.Begin); // <<<<<<<<<<<<<<<<<<<<<
EntityCollection<CustomerEntity> deserializedCustomers = (EntityCollection<CustomerEntity>)formatter.Deserialize(stream);
Assert.AreEqual(11, deserializedCustomers.Count);
foreach(CustomerEntity customer in deserializedCustomers)
{
Assert.IsTrue(customer.Employees.Count > 0);
}
}
which succeeds...
Have you set any objectid settings, have you added a custom packer to the serializer?
Joined: 30-Jun-2005
I replaced my
stream.Position =0
with
stream.Seek(0, SeekOrigin.Begin)
and I get an identical exception with the same stack trace:
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadOptimizedInt32()
CODA GUI.EXE: N 00016
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadTokenizedString(bucket As Int32)
CODA GUI.EXE: N 00013
SD.LLBLGen.Pro.ORMSupportClasses.SerializationReader.ReadOptimizedString()
CODA GUI.EXE: N 00027
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.ReadEntityMemberCollections(entity As EntityBase2)
CODA GUI.EXE: N 00160
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.ReadReferencedEntities(rootEntity As EntityBase2)
CODA GUI.EXE: N 00447
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.Deserialize(entity As EntityBase2)
CODA GUI.EXE: N 00044
SD.LLBLGen.Pro.ORMSupportClasses.FastDeserializer.Deserialize(serializedData As Byte[], root As Object)
CODA GUI.EXE: N 00148
SD.LLBLGen.Pro.ORMSupportClasses.SerializationHelper.Deserialize(entity As EntityBase2, info As SerializationInfo, context As StreamingContext)
CODA GUI.EXE: N 00039
SD.LLBLGen.Pro.ORMSupportClasses.EntityBase2..ctor(info As SerializationInfo, context As StreamingContext)
CODA GUI.EXE: N 01180
Coda.Entities.EntityClasses.CommonEntityBase..ctor(info As SerializationInfo, context As StreamingContext)
CommonEntityBase.vb: line 0054, col 04, IL 0001
Coda.Entities.EntityClasses.EmployeeEntity..ctor(info As SerializationInfo, context As StreamingContext)
EmployeeEntity.vb: line 0283, col 04, IL 0001
I'm not sure what you mean by "ObjectId settings." I don't think I'm doing anything special to the entity's hash codes or anything. I have not added a custom packer to the serializer.
I've sent a sql script to make the tables these entities are based off to support[AT]llblgen.com...hopefully it is just a datatype that I'm using
Joined: 30-Jun-2005
I've built a fresh solution with no custom code using those two entities only, and I don't have the same problem. It may have something to do with what happens in my custom overriden code in EntityCollection, or possibly with the specific relations set up one of the entities...still looking
EDIT: I'm wrong, when I set the Optimization = Fast, I get the same problem.
Same exception and everything.
To recap, this a fresh, out of the box adapter project with EmployeeEntity and EmployeeBonusEntity, and a few more relations. So, it looks like it is the extra entities (with relations to EmployeeEntity) that are causing the problem...I'll keep looking.
EDIT:
I've sent the solution+projects where this problem is demonstrated to your support email.
This issue appeared to be VB.NET and template related. Code ported from C# to VB.NET wasn't done properly, the VB.NET code had an incorrect CreateMemberEntityCollectionsQueue routine in entityIncludeAdapter.template. To fix it locally now, you have to add: Else toAdd = Nothing
to the two If statements in the routine. We'll release the public fix soon.