Should a lazy loaded collection in NHibernate ever give me a NullReferenceException? I'm getting an exception in a method like the following:
public void Test(ISession session, int id)
{
var entity = session.Load<MyEntity>(id);
entity.LazyLoadedCollection.Add(SomeItem);
}
The call to LazyLoadedCollection is throwing. My mapping looks like:
<bag lazy="true" table="MyTable">
<key>
<column name="LazyLoadedCollection" />
</key>
<many-to-many class="LazyLoadedItem">
<column name="LazyLoadedItemId" />
</many-to-many>
</bag>
Is this the expected behavior in NHibernate?
It's hard to say without seeing your class, but one thing you may not have realized is that you need to populate each collection in your class's constructor.
NHibernate will replace these collections with its own at certain times, but you still need to make sure they're initially populated with a HashedSet<T>, List<T>, or something else depending on the interface you're using.
No it's not. This is a not a good way to ask a question on the internet.
And it's really impossible to give you a direction what to do if you don't post the code throwing the exception and tell us where the exception comes from.
Related
I'm getting some very strange behavior with Linq to nHibernate.
I can retrieve all objects I want and I can add where clauses.
But in a very specific case I get the following exception:
Could not load type x.Foo.Bar.Bars. Possible cause: the assembly was
not loaded or not specified.
x.Foo.Bar.Bars is part of a piece of lambda expression in a where clause.
Where Bars is a collection of objects. The collection get filled perfectly when I just query without the where clause.
query.Where(x => x.Foo.Bar.Bars.Any(b => b.Name == "BarName"));
The stacktrace is this:
at NHibernate.Util.ReflectHelper.ClassForFullName(String classFullName)
And yes, my mapping files are embedded resources.
Part of the mapping:
<bag name ="Bars" inverse="true" lazy="false"
cascade="none" optimistic-lock="false"
access="Framework.NHibernate.Properties.EntityCollectionAccessor, Assembly">
<key column="BagId" />
<one-to-many class="Bar"/>
</bag>
access="Bars, Assembly" looks wrong. You don't want to define an access strategy that is implemented in the class Bars, do you?
I have a Sponsor object which has a collection that looks like this...
public virtual IDictionary<SettingId, object> SettingValueDefaults { get; set; }
These are actually being pulled as a subset of a larger table. I need to be able to read from these, and that is working correctly.
However, I would like to be able to make run-time changes to this collection, and have nhibernate ignore those changes, or even trying to persist the collection at all.
Again, I need nhibernate to retreive the data, so I can use it in code, but not persist the data changes I make to the collection during execution.
The mapping for this collection is below :
<map name="SettingValueDefaults" cascade="none">
<cache usage="read-write" region="Sponsors" />
<key not-null="true" column="SponsorId"/>
<index column="SettingId" type="HealthTools.Core.Domain.Model.Sponsor.Settings.SettingId, HealthTools.Core"/>
<element column="DefaultValue" type="HealthTools.Infrastructure.DataAccess.SqlVariant, HealthTools.Infrastructure"/>
<loader query-ref="GetDefaultSettingValues" />
</map>
Here is the error I am receiving from Nhibernate when tries to persist the Sponsor object.
"Invalid object name 'HealthTools.dbo.SettingValueDefaults"
This is occuring because there is no SettingsValueDefaults table, the map is just pulling data from the Sponsor.Settings table via the GetDefaultSettingValues function.
You'll want to make it read-only:
<map name="SettingValueDefaults" cascade="none" access="readonly">
I'm having an entity object called Patient and this entity is having a property called Visits which is of type VisitsCollection.
VisitsCollections is a child class of IList<Visit> but it also adds some custom logic to the collection (like auto ordering, some validation, notifications, etc..).
I need to use the custom collection type as it adds some data to the entities that are added to the collection and performs some other paperwork transparently.
Now I want to map that in NHibernate, so I've created:
<list name="Visits" lazy="true" fetch="select">
<key foreign-key="PatientId" />
<index column="Timestamp" />
<one-to-many class="Visit" not-found="ignore"/>
</list>
I'm getting an exception:
Unable to cast object of type 'NHibernate.Collection.PersistentList' to type '...VisitsCollection'
Whenever I'm accessing the visits property.
I've also tried to map it this way:
<list name="Visits" lazy="true" fetch="select" collection-type="VisitsCollection">
<key foreign-key="PatientId" />
<index column="Timestamp" />
<one-to-many class="Visit" not-found="ignore"/>
</list>
but still, I'm getting this exception:
Custom type does not implement UserCollectionType: .....VisitsCollection
I don't want to inherit my VisitsCollection from any NHibernate type as the collection class is part of a framework that I want it to be DAL-agnostic (as it will be used in many scenarios - not only with a database).
Any ideas on how to map this, preserving the structure of my code?
Thanks in advance.
I never use custom collection types, mainly because I'm lazy. NHibernate wants you to use a IUserCollectionType I believe, which requires a bit of plumbing.
Rather than that, my first stop would be to look at using extension methods as discussed by Billly McCafferty. But you have code written so...
Alternatively, you could map your collection as a component as discussed here by Colin Jack. This might be easier for your scenario?
Also check this SO thread.
I also vote up not to use custom collections. Anyway, you can do it via component.
<component name="Warehouses" class="Core.Domain.Collections.EntitySet`1[Core.Domain.OrgStructure.IWarehouseEntity,Core],Core">
<set name="_internalCollection" table="`WAREHOUSE`" cascade="save-update" access="field" generic="true" lazy="true" >
<key column="`WarehouseOrgId`" foreign-key="FK_OrgWarehouse" />
<!--This is used to set the type of the collection items-->
<one-to-many class="Domain.Model.OrgStructure.WarehouseEntity,Domain"/>
</set>
How to map NHibernate custom collection with fluentNHibernate?
Just for reference, here is how you could do it using FluentNHibernate
Whether we should or should not create a custom collection type is a separate topic IMHO
public class PatientOverride : IAutoMappingOverride<Patient>
{
public void Override(AutoMapping<Patient> mapping)
{
mapping.Component(
x => x.Visits,
part =>
{
part.HasMany(Reveal.Member<VisitsCollection, IEnumerable<Visit>>("backingFieldName")) // this is the backing field name for collection inside the VisitsCollection class
.KeyColumn("PatientId")
.Inverse(); // depends on your use case whether you need it or not
});
}
}
I've asked this elsewhere and not got any sensible reply
I'm trying to map an IDictionary. I have this mapping:
<class name="MyProject.Item, MyProject" table="Item">
<...>
<map name="Properties" access="property" table="ItemProperties" lazy="false">
<key column="ItemID" />
<index column="Idx" type="int" />
<element column="Value" type="System.Boolean, mscorlib"/>
</map>
I can persist data, but when the data is retrieved I get an nHibernate exception:
{"The value "0" is not of type "Project.PropertyType" and cannot be used in this generic collection. Parameter name: key"}
So it can't map to the enum, but why ? if I have a regular property that uses an enum, it works fine.
Is what I'm trying to do even possible ? I can't find much info on doing this.
Your mapping shows the key as an integer, not as an enum. To map the enum properly, use type="MyProject.Project.PropertyType, MyProject".
However, normally for an enum the best approach is to leave the type information out of the mapping file altogether and let NHib pick it up through reflection. My reading of the NHib source implies that if you are mapping into a generic IDictionary<K,V> then NHib should pick up the exact type of your key via reflection. IOW you still should be able to leave out the type attribute.
I have this object graph, I want to map:
abstract Account (username, password, ...)
abstract Customer (shoppingcart, orders, roles)
IndividualCustomer (user data)
CorporateCustomer (different user data, company data)
Administrator (adminroles)
How can this be mapped against one table? (I know how to do this with an entity hierarchy that is only 1 level deep, just like in the docs, but this is different).
Anybody has an idea?
I asked the same in
http://groups.google.com/group/nhusers/browse_frm/thread/7a85cba0048c18d8?hl=en, but so far have not received a useful answer.
From what I see, it should be no different than one-level-deep hierarchy.
try this:
<hibernate-mapping>
<class
name="Account"
table="..." >
<property .../>
...
<subclass
name="Customer" >
<property ... "/>
...
</subclass>
<subclass
name="IndividualCustomer" >
<property ... "/>
...
</subclass>
...
</class>
I don't have NHibernate here, to check it, but it looks like it should work. You may also want to try to nest subclass elements if it doesn't.
nesting subclasses is against the xml schema, so my guess is, it will not work.
i probably would also have to nest the discriminator declaration, which also seems hackish.
and mapping it out flat... i pass a discriminator for an abstract class, that cannot ever be used because an abstract class cannot be instantiated. seems wrong, too.
but you are right, i will try it out some time. right now it seems like a better idea to me to let customer have an account, instead of being one.
thanks!