Thread: [gentle] Bug in Gentle 1.5.0
Brought to you by:
mnmr
From: Bill S. <bso...@id...> - 2008-04-16 19:44:45
|
In ProviderFactory.cs: public static IGentleProvider GetProvider( Type type ) { NamespaceProvider np = NamespaceProviders.GetNamespaceProvider( type ); if( np != null ) { return GetProvider( np.ProviderName, np.ConnectionString, np.Schema ); // BUG } else { // use the default provider return GetProvider( null, null ); } } The marked line needs to pass a null as the initial parameter to call the correct overload. Here's the corrected source (I also changed the call to get the default provider): public static IGentleProvider GetProvider( Type type ) { NamespaceProvider np = NamespaceProviders.GetNamespaceProvider( type ); if( np != null ) { return GetProvider( null, np.ProviderName, np.ConnectionString, np.Schema ); } else { return GetDefaultProvider(); } } Bill Sorensen Objects and Infrastructure Integrated DNA Technologies |
From: Morten M. <mo...@me...> - 2008-04-16 20:37:29
|
Hi Bill, Thanks - fixed in Subversion. I changed the GetDefaultProvider() to call the destination method directly as it saves a method call. As for the C# 3.0'isms.. to the best of my knowledge these are compiler improvements and not CLR improvements, so the code will run fine on .NET 2.0 despite the use of more modern constructs. For instance, you can use the "var" keyword or the ?? operator and the code still runs fine on a 2.0 CLR. You will need to use the VS 2008 compiler though (aka csc.exe from .NET 3.5), but since the project files are VS 2008 this shouldn't be a major problem. Yours, Morten On Wed, Apr 16, 2008 at 9:44 PM, Bill Sorensen <bso...@id...> wrote: > In ProviderFactory.cs: > > public static IGentleProvider GetProvider( Type type ) > { > NamespaceProvider np = NamespaceProviders.GetNamespaceProvider( type ); > if( np != null ) > { > return GetProvider( np.ProviderName, np.ConnectionString, np.Schema > ); // BUG > } > else > { > // use the default provider > return GetProvider( null, null ); > } > } > The marked line needs to pass a null as the initial parameter to call the > correct overload. Here's the corrected source (I also changed the call to > get the default provider): > > public static IGentleProvider GetProvider( Type type ) > { > NamespaceProvider np = NamespaceProviders.GetNamespaceProvider( type ); > > if( np != null ) > { > return GetProvider( null, np.ProviderName, np.ConnectionString, > np.Schema ); > } > else > { > return GetDefaultProvider(); > } > } > > > Bill Sorensen > Objects and Infrastructure > Integrated DNA Technologies > > > ------------------------------------------------------------------------- > This SF.net email is sponsored by the 2008 JavaOne(SM) Conference > Don't miss this year's exciting event. There's still time to save $100. > Use priority code J8TL2D2. > > http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone > _______________________________________________ > Gopf-devel mailing list > Gop...@li... > https://lists.sourceforge.net/lists/listinfo/gopf-devel > > -- Yours, Morten |
From: Bill S. <bso...@id...> - 2008-04-16 22:00:32
|
Hi Morten, Thanks for updating that - I don't have much experience with Subversion. I ran into another bug, this one in the FieldMap class: public bool IsGenericNullableType { get { return memberType.FullName.StartsWith( "System.NullableType" ) && memberType.IsGenericType; } The type names will actually start with just "System.Nullable". A coworker (Neil McEntaggart) suggested the following alternative to eliminate the string constant: return memberType.IsGenericType && (memberType.GetGenericTypeDefinition() == typeof(Nullable<>)); This bug was rather difficult to locate; there appears to be an issue with the isPerfectMatch field in ConstructorMap. When public IEntity Construct( object[] row, PersistenceBroker broker ) is called, isPerfectMatch can return different values for the same business object and row values. Our unit tests (separate from the Gentle.NET tests) would fail sometimes due to the generic bug (isPerfectMatch was false, so GetParams was called) but would succeed if run individually (isPerfectMatch would then return true). Given the same persistent object and the same row, I would think isPerfectMatch would not vary. Thanks again, Bill Sorensen Objects and Infrastructure Integrated DNA Technologies ________________________________ From: gop...@li... [mailto:gop...@li...] On Behalf Of Morten Mertner Sent: Wednesday, April 16, 2008 3:38 PM To: Gentle development Subject: Re: [gentle] Bug in Gentle 1.5.0 Hi Bill, Thanks - fixed in Subversion. I changed the GetDefaultProvider() to call the destination method directly as it saves a method call. As for the C# 3.0'isms.. to the best of my knowledge these are compiler improvements and not CLR improvements, so the code will run fine on .NET 2.0 despite the use of more modern constructs. For instance, you can use the "var" keyword or the ?? operator and the code still runs fine on a 2.0 CLR. You will need to use the VS 2008 compiler though (aka csc.exe from .NET 3.5), but since the project files are VS 2008 this shouldn't be a major problem. Yours, Morten On Wed, Apr 16, 2008 at 9:44 PM, Bill Sorensen <bso...@id...> wrote: In ProviderFactory.cs: public static IGentleProvider GetProvider( Type type ) { NamespaceProvider np = NamespaceProviders.GetNamespaceProvider( type ); if( np != null ) { return GetProvider( np.ProviderName, np.ConnectionString, np.Schema ); // BUG } else { // use the default provider return GetProvider( null, null ); } } The marked line needs to pass a null as the initial parameter to call the correct overload. Here's the corrected source (I also changed the call to get the default provider): public static IGentleProvider GetProvider( Type type ) { NamespaceProvider np = NamespaceProviders.GetNamespaceProvider( type ); if( np != null ) { return GetProvider( null, np.ProviderName, np.ConnectionString, np.Schema ); } else { return GetDefaultProvider(); } } Bill Sorensen Objects and Infrastructure Integrated DNA Technologies ------------------------------------------------------------------------ - This SF.net email is sponsored by the 2008 JavaOne(SM) Conference Don't miss this year's exciting event. There's still time to save $100. Use priority code J8TL2D2. http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/j avaone _______________________________________________ Gopf-devel mailing list Gop...@li... https://lists.sourceforge.net/lists/listinfo/gopf-devel -- Yours, Morten |
From: Morten M. <mo...@me...> - 2008-04-16 22:56:09
|
Hi Bill, > A coworker (Neil McEntaggart) suggested the following alternative to eliminate the string constant: > > return memberType.IsGenericType && > (memberType.GetGenericTypeDefinition() == typeof(Nullable<>)); Much nicer, thanks! Fixed in Subversion. > This bug was rather difficult to locate; there appears to be an > issue with the isPerfectMatch field in ConstructorMap. When public > IEntity Construct( object[] row, PersistenceBroker broker ) is > called, isPerfectMatch can return different values for the same > business object and row values. Our unit tests (separate from the > Gentle.NET tests) would fail sometimes due to the generic bug > (isPerfectMatch was false, so GetParams was called) but would > succeed if run individually (isPerfectMatch would then return true). > Given the same persistent object and the same row, I would think > isPerfectMatch would not vary. Hmm, it's not perfectly clear to me what the cause could be for this, but two things do come to mind. The first is that Gentle caches the ConstructorMap instance, and that its field values are determined using the column names and associated row values passed in initially. When the same column names are encountered later the cached CM is retrieved and reused under the assumption that the data row will be compatible. My best guess is that because Gentle does not convert data read from the database to nullable types, the CM might get initialized erroneously if the initial row contains data and later rows contain nulls (and possibly vice versa too). Without having tested the code, I believe changing line 123 of CM to the following will fix the problem: if( fm.NullValue != null || ( row[ i ] != null && fm.Type != row[ i ].GetType() && ! fm.IsGenericNullableType ) ) In the ideal world one would instead check that the type argument of the nullable type matches the row type, but that is left as an exercise for the reader in case the above fix works ;) Yours, Morten |
From: Bill S. <bso...@id...> - 2008-04-17 14:56:32
|
Thank you! That makes the test results consistent. (I did not do extensive additional testing, though.) -Bill Sorensen -----Original Message----- From: gop...@li... [mailto:gop...@li...] On Behalf Of Morten Mertner Sent: Wednesday, April 16, 2008 5:56 PM To: Gentle development Subject: Re: [gentle] Bug in Gentle 1.5.0 [snip] Without having tested the code, I believe changing line 123 of CM to the following will fix the problem: if( fm.NullValue != null || ( row[ i ] != null && fm.Type != row[ i ].GetType() && ! fm.IsGenericNullableType ) ) In the ideal world one would instead check that the type argument of the nullable type matches the row type, but that is left as an exercise for the reader in case the above fix works ;) Yours, Morten |
From: Morten M. <mo...@me...> - 2008-04-17 15:25:34
|
Hi Bill, > Thank you! That makes the test results consistent. (I did not do > extensive additional testing, though.) Good news; the change has been checked in to Subversion. Yours, Morten |
From: Bill S. <bso...@id...> - 2008-04-17 16:29:25
|
I set up a test database using the MSSQLServer script and got most of the official Gentle.NET 1.5.0 framework unit tests to run after setting up a Gentle.config and disabling all the non-MSSQL tests. (I wasn't testing caching or uniquing, either.) Four tests still failed. I believe the TableColumn attribute is defined incorrectly on one of the test business objects, and the script did not set up a required view. In other words, these are test bugs, not bugs in Gentle. Details: TestDateTimeNullValue.TestMinValue - There is no NullValue defined on the TableColumn for the business object. TestList.TestAnalyzerWithView - The MSSQLServer.sql script does not set up the MailingList view. TestObjectMap.TestMapConstruction - fm.NullValue is null. TestPropertyHolder.TestCRUD - Also assumes DateTime.MinValue will result in NULL being written. Just an FYI for anyone trying to get the tests to work. Thanks, Bill Sorensen Objects and Infrastructure Integrated DNA Technologies -----Original Message----- From: gop...@li... [mailto:gop...@li...] On Behalf Of Morten Mertner Sent: Thursday, April 17, 2008 10:25 AM To: Gentle development Subject: Re: [gentle] Bug in Gentle 1.5.0 Hi Bill, > Thank you! That makes the test results consistent. (I did not do > extensive additional testing, though.) Good news; the change has been checked in to Subversion. Yours, Morten |
From: Morten M. <mo...@me...> - 2008-04-21 14:48:41
|
Hi Bill, thank you for being such a thorough fellow :-) > TestDateTimeNullValue.TestMinValue - There is no NullValue defined on > the TableColumn for the business object. This should be fine, as Gentle is supposed to assign a default NullValue when no explicit value is specified. Additional thinking on this reveals that Gentle only assigns a default NullValue when the schema analyzer is enabled. Most likely you have disabled it in the configuration file (the tests did work here with Analyzer enabled). I've changed the initialization order in FieldMap so that the default NullValue isn't overwritten by an unspecified null value (which used to be what the analyzer would later re-correct). Hence, the analyzer is no longer required to get proper defaults. > TestList.TestAnalyzerWithView - The MSSQLServer.sql script does not set > up the MailingList view. MailingList actually maps to a regular table. Fixed by commenting the test case. I believe it once did test a view, but my test database doesn't have a view either. My guess is that someone (myself included) fixed the test by mapping the MailingList class to the List table rather than by creating the appropriate database view. Adding some tests exercising views would be useful, but is somewhat beyond the quick-fix efforts I do throw at Gentle. > TestObjectMap.TestMapConstruction - fm.NullValue is null. > TestPropertyHolder.TestCRUD - Also assumes DateTime.MinValue will result > in NULL being written. Enabling the schema analyzer (or grabbing the latest from Subversion) will also fix these. Yours, Morten |
From: Bill S. <bso...@id...> - 2008-04-21 14:57:43
|
Hi Morten, Yes, I had Analyzer set to None. Sorry, I didn't think of that. Thanks much for reviewing these! - Bill Sorensen -----Original Message----- From: gop...@li... [mailto:gop...@li...] On Behalf Of Morten Mertner Sent: Monday, April 21, 2008 9:48 AM To: Gentle development Subject: Re: [gentle] Bug in Gentle 1.5.0 Hi Bill, thank you for being such a thorough fellow :-) > TestDateTimeNullValue.TestMinValue - There is no NullValue defined on > the TableColumn for the business object. This should be fine, as Gentle is supposed to assign a default NullValue when no explicit value is specified. Additional thinking on this reveals that Gentle only assigns a default NullValue when the schema analyzer is enabled. Most likely you have disabled it in the configuration file (the tests did work here with Analyzer enabled). I've changed the initialization order in FieldMap so that the default NullValue isn't overwritten by an unspecified null value (which used to be what the analyzer would later re-correct). Hence, the analyzer is no longer required to get proper defaults. > TestList.TestAnalyzerWithView - The MSSQLServer.sql script does not > set up the MailingList view. MailingList actually maps to a regular table. Fixed by commenting the test case. I believe it once did test a view, but my test database doesn't have a view either. My guess is that someone (myself included) fixed the test by mapping the MailingList class to the List table rather than by creating the appropriate database view. Adding some tests exercising views would be useful, but is somewhat beyond the quick-fix efforts I do throw at Gentle. > TestObjectMap.TestMapConstruction - fm.NullValue is null. > TestPropertyHolder.TestCRUD - Also assumes DateTime.MinValue will > result in NULL being written. Enabling the schema analyzer (or grabbing the latest from Subversion) will also fix these. Yours, Morten |
From: Morten M. <mo...@me...> - 2008-04-21 15:07:17
|
Hi Bill, > Yes, I had Analyzer set to None. Sorry, I didn't think of that. > Thanks much for reviewing these! You're welcome. Btw, I forgot to mention what might be important to some: I modified the default type mapping for string (.NET) from Text to NVarChar, as the test cases would otherwise need additional TableColumn decorations to work without analyzer. This might affect people who aren't using the analyzer at all but is generally much nicer as the Text data type has severe query restrictions. Yours, Morten |
From: Bill S. <bso...@id...> - 2008-04-21 15:23:49
|
For our company, we changed public override long GetDbType( Type type ) in SqlServerFactory (Gentle.Provider.SQLServer) to use: else if( type.Equals( typeof(string) ) ) { result = SqlDbType.NVarChar; // was Text } quite some time ago. I think this was a good move. Thanks, Bill Sorensen -----Original Message----- From: gop...@li... [mailto:gop...@li...] On Behalf Of Morten Mertner Sent: Monday, April 21, 2008 10:07 AM To: Gentle development Subject: Re: [gentle] Bug in Gentle 1.5.0 Hi Bill, > Yes, I had Analyzer set to None. Sorry, I didn't think of that. > Thanks much for reviewing these! You're welcome. Btw, I forgot to mention what might be important to some: I modified the default type mapping for string (.NET) from Text to NVarChar, as the test cases would otherwise need additional TableColumn decorations to work without analyzer. This might affect people who aren't using the analyzer at all but is generally much nicer as the Text data type has severe query restrictions. Yours, Morten |
From: Morten M. <mo...@me...> - 2008-04-21 15:41:37
|
Hi Bill, > For our company, we changed [...] > quite some time ago. I think this was a good move. I probably should have too, but then it only affected people not using the analyzer, which I suspect isn't very many. Yours, Morten |
From: Martín M. <mar...@gm...> - 2008-04-17 16:38:36
|
On Apr 17, 2008, at 5:25 PM, Morten Mertner wrote: > Good news; the change has been checked in to Subversion. This will trigger a 1.5.1 release and we'll be back on the road, with "periodic" gentle releases. :) Morten, you can't escape Gentle that easily. ;) Ok; I was dreaming. -- Martin Marconcini "A complex part of programming doesn't even involve writing code. I am referring to the interaction between computer programs and people. User interaction is a complex subject that has been the subject of many books." Annonymous. |
From: Morten M. <mo...@me...> - 2008-04-21 14:58:51
|
Hi Martín, >> Good news; the change has been checked in to Subversion. > This will trigger a 1.5.1 release and we'll be back on the road, with > "periodic" gentle releases. :) Haha, we'll see. I'm happy to invest a little time fixing bugs when people can supply me with specifics to guide me, but given that I'm primarily using Entity Framework myself it's unlikely that there'll be any improvements beyond this. > Morten, you can't escape Gentle that easily. ;) Obviously :) but as long as time permits I enjoy working on it. Always fun to revisit old code (cough, cough ;-) > Ok; I was dreaming. [Morten swings into a suit and puts on a CEO cap] Codeworks will be happy to have Morten spend his time developing Gentle features. I'm sure a very reasonable rate can be negotiated for such custom developments ;-) [Morten swings back into comfy gear] Such a nice boss to have! ;) Yours, Morten |
From: Bill S. <bso...@id...> - 2008-04-21 16:07:20
|
Hi Morten, I'm assuming you mean the Microsoft Entity Framework? I'm not sure if this is the place for this, but I (for one) would be very interested in your opinions of the EF. What does it offer that Gentle.NET does not? What are its strengths and weaknesses? How does it perform/scale? Why did you choose it (if you were involved in the decision)? Thanks much, Bill Sorensen -----Original Message----- From: gop...@li... [mailto:gop...@li...] On Behalf Of Morten Mertner Sent: Monday, April 21, 2008 9:59 AM To: Gentle development Subject: Re: [gentle] Bug in Gentle 1.5.0 [snip] given that I'm primarily using Entity Framework myself it's unlikely that there'll be any improvements beyond this. [snip] |
From: Morten M. <mo...@me...> - 2008-04-21 17:44:38
|
Hi Bill, > I'm assuming you mean the Microsoft Entity Framework? I'm not sure if > this is the place for this, but I (for one) would be very interested in > your opinions of the EF. What does it offer that Gentle.NET does not? > What are its strengths and weaknesses? How does it perform/scale? Why > did you choose it (if you were involved in the decision)? My primary source of income is from being instructor on various .NET programming classes (mostly but not exclusively MOC material), so I try to force-feed myself most new things that come out ;) EF is Microsoft's first bid (not counting everything that was never really released) at producing an ORM and if they follow up on promises to make it a first-class citizen in many of their business-line products (like MOSS, SQL Server, etc) then it will soon be unavoidable anyway. It also builds on LINQ and the whole F#/lambda she-bang, which is really clever and something I wanted to experiment with anyway. Before I get to EF I'd like to comment that I actually started out by trying NHibernate with Castle ActiveRecord, but either I wasn't competent enough to figure it out or it's a hopeless framework. I spent inordinate amounts of time doing fairly simple stuff and in the end wasn't very pleased with anything but it's ability to auto-create the database schema. YMMW ;) To keep this post within a reasonable length, I've listed various key points in response to your questions. Let me know if you want me to elaborate on any of them. EF pro/con: + Graphical designer (buggy/unfinished but already nice as is) - Beta2 will not serialize entity graphs (but final will according to blogs), and so is unsuitable for WCF. + LINQ for queries = type safety = good. - Because LINQ is unified across many targets there's no option to specify the kind of join you want (always an inner join). This is likely to cause some frustration here and there. - Many standard LINQ operators unsupported at this time (which translates into not being able to use database queries for some filtering tasks). - Objects are change-tracked; this is both a plus because EF can be clever at times, but makes stuff more complicated when you aren't using the same tracker instance (which you won't be for stateless applications, e.g. ASP.NET and WCF stuff). Since I do mostly web development this is a minus although it's supposedly a feature. It also sometimes forces you to retrieve objects (or cache their entity key) just to be able to add a relation or child entity. o I find myself writing helper methods for CRUD and other operations. Complex queries are fairly easy to compose although some Googling is required to figure out the exact syntax. I'm still undecided whether this is good or bad, but think there is room for the code generator to provide more assistance for simple/obvious things. + It's easy to do both lazy and eager loading, as well as static sorting (sort key embedded as part of query). - Dynamic sorting based on string parameter is only possible by constructing a custom lambda expression (complex but reusable). - No enum support (yet), not even in queries. No casting inside queries either so working with enums is bothersome. + Reasonably fast. Although I have no numbers to back this up my initial experience is that performance is good. + Model generator (schema -> entity model). Final is supposed to also support the other way around. o Code generator produces big single file. Nicer to include in VS projects but not very nice for locating/inspecting things. I wish they'd generate an entire Model project with individual files in it. - Still quite a few bugs and limitations in the current beta. EF vs Gentle: - I really dislike that you have to be connected to the data store to compose a query. + Because the code generator analyzes the schema there is no runtime overhead for this as there is with Gentle. OTOH is has to parse lots of XML so it might not be much ;-) - Because you have to be connected to the data store to compose queries there is a tendency for the data layer to seep upwards unless you explicitly create helper classes to keep it out. + LINQ, designer support, joins and complex queries, lazy/eager loading, type-safe queries, etc. All scores for EF. o No NullValue support. It's a primitive solution but nonetheless works rather well (except for bools). Using Nullable<T> leads to lots of HasValue/Value checks which I find is smelly code. That's all I can think of right now ;) Yours, Morten |