|
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
|