From: Fabio M. (JIRA) <nh...@gm...> - 2011-05-17 18:59:45
|
[ http://216.121.112.228/browse/NH-2568?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ] Fabio Maulo updated NH-2568: ---------------------------- Priority: Minor (was: Major) Issue Type: Improvement (was: Bug) Summary: Create Custom Persister for Collection Type inherited from OneToManyPersister (was: Cannot Create Custom Persister for Collection Type) > Create Custom Persister for Collection Type inherited from OneToManyPersister > ----------------------------------------------------------------------------- > > Key: NH-2568 > URL: http://216.121.112.228/browse/NH-2568 > Project: NHibernate > Issue Type: Improvement > Components: Core > Affects Versions: 3.0.0.GA > Reporter: Jeff Greenland > Priority: Minor > > Encountered issue where setting a Persister Type on a collection property (specifically a type of List) would throw a NullPointerException when NHibernate initialized. Our persister, called MyPersister as a test, extended OneToManyPersister and only had a constructor defined which matched the constructor in the base class (OneToManyPersister). Here's our analysis as to why it looks like a bug: > Tracing through the code revealed that a constructor was not found on MyPersister matching the expected arguments. Those arguments are defined on line 34 of PersisterFactory.cs for CollectionPersister types and are Mapping.Collection, ICacheConcurrencyStrategy, and ISessionFactoryImplementor. > In the CreateCollectionPersister() method (line 68), if there is no persister class defined, it calls the OneToManyPersister implementation of ICollectionPersister with Mapping.Collection, ICacheConcurrencyStrategy, Configuration, and ISessionFactoryImplementor parameters. However, if a custom persister class is defined, it calls the Create() method (line 124) with the Configuration parameter missing, and consequently the Create() method does not invoke a matching constructor with that parameter. > It seems to us that since the default persister class of OneToManyPersister accepts the 4 argument constructor, and if you specified a custom persister that extends OneToManyPersister, the custom persister should accept the same 4 arguments. In other words, if I specify a custom persister on my class as OneToManyPersister (the same as the default), NHibernate would fail to initialize because it couldn't construct OneToManyPersister. > Looks related to NH-1957, which appears to have been immediately closed. I've included our diff below that seems to have fixed the issue. > Diff: > Index: PersisterFactory.cs > =================================================================== > --- PersisterFactory.cs (revision 31412) > +++ PersisterFactory.cs (revision 31413) > @@ -31,14 +31,15 @@ > > // TODO: is it really necessary to provide Configuration to CollectionPersisters ? Should it not be enough with associated class ? > // or why does ClassPersister's not get access to configuration ? > - private static readonly System.Type[] CollectionPersisterConstructorArgs = new System.Type[] > + private static readonly System.Type[] CollectionPersisterConstructorArgs = new System.Type[] > { > typeof(Mapping.Collection), > typeof(ICacheConcurrencyStrategy), > + typeof(Configuration), > typeof(ISessionFactoryImplementor) > }; > > - /// <summary> > + /// <summary> > /// Creates a built in Entity Persister or a custom Persister. > /// </summary> > public static IEntityPersister CreateClassPersister(PersistentClass model, ICacheConcurrencyStrategy cache, > @@ -78,10 +79,11 @@ > } > else > { > - return Create(persisterClass, model, cache, factory); > + return (ICollectionPersister) Create(persisterClass, model, cache, cfg, factory); > } > } > > + > /// <summary> > /// Creates a specific Persister - could be a built in or custom persister. > /// </summary> > @@ -122,7 +124,7 @@ > } > > public static ICollectionPersister Create(System.Type persisterClass, Mapping.Collection model, > - ICacheConcurrencyStrategy cache, ISessionFactoryImplementor factory) > + ICacheConcurrencyStrategy cache, Configuration cfg, ISessionFactoryImplementor factory) > { > ConstructorInfo pc; > try > @@ -136,8 +138,8 @@ > > try > { > - return (ICollectionPersister) pc.Invoke(new object[] {model, cache, factory}); > - } > + return (ICollectionPersister)pc.Invoke(new object[] { model, cache, cfg, factory }); > + } > catch (TargetInvocationException tie) > { > Exception e = tie.InnerException; > @@ -155,5 +157,6 @@ > throw new MappingException("Could not instantiate collection persister " + persisterClass.Name, e); > } > } > + > } > } -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://216.121.112.228/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira |