Handled Exception comes back

Posts   
 
    
shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 07-Feb-2007 16:34:38   

Hi,

i'm using adapter in C# (.Net 2.0) with firebird 2.0.

i must save various entities in different methods. no i have the following problem:

in method A i try to store entity E1, but this fails because of a unique key constraint. the upcoming exception is caught and next the application runs method B. in mehtod B entity E2 should be stored - but there comes the exception for uq key violation from entity E1 again so i can't store entity E2 thought for this entity were no exceptions! Why????? frowning

in both methods i instanciate a new DataAccessAdapter and dispose it at the end of the method. normally i use no transaction. but i've tried this in method A:


Trans2LesEntity oT2L = new Trans2LesEntity();
oT2L.Lesson = oLesson;
oT2L.Translation = oTrans;
oDA.StartTransaction(IsolationLevel.ReadCommitted, "Translation");
try
{
           oDA.SaveEntity(oT2L);
           oDA.Commit();
}
catch
{
            writeLogLine("ERROR !");
            oDA.Rollback();
}
oDA.CloseConnection();
oDA.Dispose();

this fails correctly with an exception. but a store action after a so handled exception should succeed!

What's going wrong??????

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 07-Feb-2007 17:12:43   

Would you please the 2 entities tables structures, illustrating PKs, UKs & FKs.? Also stating any identity fields.

It seems to me that E2 have a non-nullable FK to Entity E1, and this was missing when you were saving it.

shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 07-Feb-2007 17:24:45   

Walaa wrote:

Would you please the 2 entities tables structures, illustrating PKs, UKs & FKs.? Also stating any identity fields.

It seems to me that E2 have a non-nullable FK to Entity E1, and this was missing when you were saving it.

the entities have nothing in common. and if i prevent storing violating E1 entities by doing this:

if (!oDA.FetchEntityUsingUniqueConstraint(oT2L,
oT2L.ConstructFilterForUCTranslationidLessonid())) { oDA.SaveEntity(oT2L); }

the entity E2 is stored without a problem. thus shows that the problem is the exception which is thrown by storing a key violating E1 in a method before. why is a exception from earlier statement is raised again????

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 07-Feb-2007 18:14:25   

That's a strange behaviour, can you re-produce it on SQL Server database or MS Access? Also which runtimeLibrary version are you using?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 07-Feb-2007 20:54:46   

Adapter saves recursively by default. So if E1 is first in the graph, and you save any entity in the graph (E1, E2 etc.) it will recursively be saved, so E1 will be the first entity to save, no matter what.

If you don't want to do this, just save E2, then specify false for 'recurse' in an overload of SaveEntity()

Frans Bouma | Lead developer LLBLGen Pro
shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 08-Feb-2007 08:19:05   

Walaa wrote:

That's a strange behaviour, can you re-produce it on SQL Server database or MS Access? Also which runtimeLibrary version are you using?

What does runtimeLibrary version in this context mean? i'm using .Net 2.0 framework with visual studio 2005, the rountime version from firebird client is v2.0.50727 (Version 2.0.1.0).

Otis wrote:

Adapter saves recursively by default. So if E1 is first in the graph, and you save any entity in the graph (E1, E2 etc.) it will recursively be saved, so E1 will be the first entity to save, no matter what.

No, both entities have no other entities fetched - they are not in an graph.

i remember i had exactly the same problem before and i have only solved it by checking if a entity allready exists.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 08-Feb-2007 08:36:50   

Check the following thread to know how to get the runtimeLibrary version: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7725

shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 08-Feb-2007 08:48:45   

Walaa wrote:

Check the following thread to know how to get the runtimeLibrary version: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7725

ok i've found it. the runtimeVersion is v2.0.50727

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 08-Feb-2007 09:01:47   

v2.0.50727 is a way old release, would you please download and use the latest version. Thanks. (Better to download the Full version installer).

shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 12-Feb-2007 10:03:34   

Walaa wrote:

v2.0.50727 is a way old release, would you please download and use the latest version. Thanks. (Better to download the Full version installer).

i've downloaded the newest version from gen pro and installed it. but the version number shown in the properties has not changed. i have also download the latest runtime libaries and copy it to the correct directory. nothing changed!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 12-Feb-2007 10:28:08   

You're both looking at the .NET version number. The runtime libraries BUILD number is obtainable as described in the manual and here: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7725

I'll now look into your problem, which is a little hard as you post a codesnippet with names which don't match your problem description. Which entity is E1 and which entity is E2?

Please be clear about this, it's otherwise hard to come up with a solution, as I now have to guess what E1 and E2 are. We don't have the guidelines for nothing.

I see oT2L, oLesson and oTranslation. Which one is E1 and which one is E2? If something goes wrong in method B, why aren't you posting that? Clearly, E1 is saved again, so it must be associated with the entity you're saving, e.g. if you do: oT2L.Lession = oLesson; and save oT2L, oLesson is saved as well.

So please provide some more information, I can't see what's wrong now without REAL names and REAL code.

Frans Bouma | Lead developer LLBLGen Pro
shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 14-Feb-2007 17:29:39   

Otis wrote:

You're both looking at the .NET version number. The runtime libraries BUILD number is obtainable as described in the manual and here: http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=7725 ...

So please provide some more information, I can't see what's wrong now without REAL names and REAL code.

hi, sorry for answering so late.

i have a little problem by finding "runtime libraries BUILD number". in the thread you've referenced, there is only the "Runtime library version" mentioned.

And here now the realcode:

This is the first statement which "correctly" fails (already shown above)


Trans2LesEntity oT2L = new Trans2LesEntity();
oT2L.Lesson = oLesson;
oT2L.Translation = oTrans;
oDA.StartTransaction(IsolationLevel.ReadCommitted, "Translation");
try
{
         oDA.SaveEntity(oT2L);
         oDA.Commit();
}
catch
{
            writeLogLine("ERROR !");
            oDA.Rollback();
}
oDA.CloseConnection();
oDA.Dispose();

And after this, in a directly following method, this code is executed:


DataAccessAdapter oDA = new DataAccessAdapter();
LanguageEntity oLanguage = (LanguageEntity)m_oLanguageHash[strLangCode];
ForeignwordEntity oForWord = new ForeignwordEntity();
oForWord.Vocable = oVocable;
oForWord.Language = oLanguage;
// handle possible double Entry 
if (oDA.FetchEntity(oForWord))
{
        if (!oForWord.Word.Equals(strWord))
        {
                  writeLogLine("ERROR - createForeignTranslations!");
        }
}
else
{
        oForWord.Word = strWord;
        oDA.SaveEntity(oForWord);
}
oDA.CloseConnection();
oDA.Dispose();


and by executing the oDA.SaveEntity(oForWord) appears the exception for the unique key violation for the first "correctly" failed code segment. if this segment is not executed, the oDA.SaveEntity(oForWord) from the second code segment does not fail!

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 15-Feb-2007 07:46:59   

The runtimeLibrary version or build, the following is how you get the RTL version, from the above mentioned thread:

When it's a problem occuring at runtime, post the Runtime library version. The runtime library version is obtainable by rightclicking the SD.LLBLGen.Pro.ORMSupportClasses.NETxy.dll in windows explorer and then by selecting properties and the version tab. The version is then enlisted at the top as the fileversion. It has the typical format as 2.0.0.YYMMDD, or starting in 2007, the format 2.0.YY.MMDD

Also the following is copied from the manual:

You can request the version of the runtime libraries you're currently using in your code using: // C# string version = SD.LLBLGen.Pro.ORMSupportClasses.RuntimeLibraryVersion.Version + "." + SD.LLBLGen.Pro.ORMSupportClasses.RuntimeLibraryVersion.Build; ' VB.NET Dim version As String = SD.LLBLGen.Pro.ORMSupportClasses.RuntimeLibraryVersion.Version & "." & _ SD.LLBLGen.Pro.ORMSupportClasses.RuntimeLibraryVersion.Build The runtime libraries also use a file version attribute, which is visible when you rightclick in windows explorer on the assembly dll (one of the DQE assemblies or the ORM Support classes assembly) and select 'Properties' and after that view the Version tab. This version has the following format: 2.0.0.yymmdd, where yymmdd is the date the assembly was released.

shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 15-Feb-2007 08:41:20   

Sorry i was on the wrong track. i have always looked in visual studio and get the wrong number. i was wrong - but as people say: who could read has clearly an advantage.

the RTL version is 2.0.0.061205

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39613
Joined: 17-Aug-2003
# Posted on: 15-Feb-2007 11:14:58   

Ok, I think this is what happens: when you do this: oT2L.Lesson = oLesson; oT2L.Translation = oTrans;

you also associating oT2L with oLesson, namely it's added to oLesson.Trans2LesCollection (or whatever it's named). Same for oTrans.

So in the next routine if you do this: oForWord.Vocable = oVocable; oForWord.Language = oLanguage;

and oVocable or oLanguage has a reference to the previously used oLesson or oTrans, it will thus run into oT2L.

To test this, add this to the catch clause of the first routine so it will look like this:

catch
{
            writeLogLine("ERROR !");
            oT2L.Lesson = null;
            oT2L.Translation = null;
            oDA.Rollback();
}

The problem is graph versioning in-memory. You setup a graph to persist, however, half way it fails. To go back to the original graph means all participating entities have to be reset to the point before the graph setup started. This is a very complex subject and we didn't implement graph versioning yet (if ever, we tried a couple of times, but it's very very complex to do it right AND performant).

Frans Bouma | Lead developer LLBLGen Pro
shennig
User
Posts: 48
Joined: 14-Nov-2006
# Posted on: 15-Mar-2007 09:35:43   

Otis wrote:

The problem is graph versioning in-memory. You setup a graph to persist, however, half way it fails. To go back to the original graph means all participating entities have to be reset to the point before the graph setup started. This is a very complex subject and we didn't implement graph versioning yet (if ever, we tried a couple of times, but it's very very complex to do it right AND performant).

Ok, it's a little bit late for reply, but i run twice in this problem and the solution to set the relations from the object oT2L too NULL and then make a rollback works. i had not in mind, that i use the same objects, like the translation object, and that gen pro tries to store recursivly - so the abortive save action is tried again and leeds to the same error. Now it's clear why this exception comes back!

thank you for help!