try to fetch the associations in a separate criteria (use MultiCriteria to
have it done in a single roundtrip)
NH should be able to wire everything up.
On Sun, Sep 14, 2008 at 7:31 PM, Ben Hart <[EMAIL PROTECTED]> wrote:
> Hi all
>
> I have a parent class which has a list of versions (one-to-many), and the
> version has a collection of associations (many-to-many). The basic idea is
> that the parent has versions over time, and within each version there will
> be different associations. I've included the classes and mappings below, an
> attempt by me to distil the idea of what i'm trying to do into the simplest
> case possible.
>
> I've been trying to reduce the number of queries fired. When getting many
> of the type I'd like to keep the lazy loading, when getting the individual
> by id I'd like to get as much as possible in one select (there are small
> numbers of each of the children, and they are guaranteed to be used). I'm
> using Criteria. The problem is that the version list contains duplicates due
> to the join via the many-to-many. I've read Ken's recent post on removing
> duplicates, the FAQ, and have pored over many other posts. I understand why
> the duplicates are there, and have seen the various options for removing
> them, I just can't get them to work on the "child collection". I'm sure what
> I'm trying to do is possible, I'm just going round in circles, in the dark,
> without much certainty of what direction i should head.
>
> I've tried the following criteria, which successfully execute in one sql
> statement, but return a parent that has duplicated versions:
> Parent parent = session.CreateCriteria(typeof(Parent))
> .SetFetchMode("Versions", FetchMode.Join)
> .SetFetchMode("Versions.Associations", FetchMode.Join)
> .SetResultTransformer(new
> DistinctRootEntityResultTransformer())
> .Add(Restrictions.IdEq(id))
> .UniqueResult<Parent>();
>
> Parent parent = session.CreateCriteria(typeof(Parent))
> .CreateAlias("Versions", "version", JoinType.LeftOuterJoin)
> .CreateAlias("version.Associations", "association",
> JoinType.LeftOuterJoin)
> .SetResultTransformer(new
> DistinctRootEntityResultTransformer())
> .Add(Restrictions.IdEq(id))
> .UniqueResult<Parent>();
>
> And various combinations of the above. I've also attempted to use a
> detached criterion for the version collection, but I'm really not sure how
> to wire it in. I've also tried creating more criteria inline
> (.CreateCriteria("Versions..), but this seems to execute the same query
> twice. I am happy to remove the duplicates in the version collection after
> the query if this is necessary, but i suspect that it is not (which is what
> I understand the DictinctRootEntityResultTransformer does, I just want it to
> work it's magic against a child collection).
>
> Thanks in advance for any advice.
>
> Ben
>
>
> If of use, the distilled model looks something like this:
>
> public class Parent
> {
> public virtual int Id { get; set; }
> public virtual string Name { get; set; }
> public virtual IList<ParentVersion> Versions { get; set; }
>
> public Parent()
> {
> Versions = new List<ParentVersion>();
> }
> }
>
> public class ParentVersion
> {
> public virtual int Id { get; set; }
> public virtual string Address { get; set; }
> public virtual Parent Parent { get; set; }
> public virtual IList<Association> Associations { get; set; }
>
> public ParentVersion()
> {
> Associations = new List<Association>();
> }
> }
>
> public class Association
> {
> public virtual int Id { get; set; }
> public virtual Parent Parent { get; set; }
> public virtual string Name { get; set; }
> }
>
> Mappings:
>
> <class name="TestNHJoin.Parent, TestNHJoin" table="Parent">
> <id name="Id" type="System.Int32" column="Id" unsaved-value="0">
> <generator class="hilo">
> <param name="table">hibernate_unique_key</param>
> <param name="column">next_hi</param>
> <param name="max_lo">1</param>
> </generator>
> </id>
> <property name="Name" type="System.String" />
>
> <bag name="Versions" cascade="save-update">
> <key>
> <column name="ParentId" not-null="true" />
> </key>
> <one-to-many class="TestNHJoin.ParentVersion, TestNHJoin" />
> </bag>
>
> </class>
>
> <class name="TestNHJoin.ParentVersion, TestNHJoin" table="ParentVersion">
> <id name="Id" type="System.Int32" column="Id" unsaved-value="0">
> <generator class="hilo">
> <param name="table">hibernate_unique_key</param>
> <param name="column">next_hi</param>
> <param name="max_lo">1</param>
> </generator>
> </id>
>
> <many-to-one name="Parent" class="TestNHJoin.Parent, TestNHJoin">
> <column name="ParentId" not-null="false" />
> </many-to-one>
>
> <property name="Address" type="System.String" />
>
> <bag name="Associations" table="ParentVersionAssociations"
> cascade="all">
> <key column="ParentVersionId" />
> <many-to-many class="TestNHJoin.Association, TestNHJoin"
> column="AssociationId" />
> </bag>
>
> </class>
>
> <class name="TestNHJoin.Association, TestNHJoin" table="Association">
> <id name="Id" type="System.Int32" column="Id" unsaved-value="0">
> <generator class="hilo">
> <param name="table">hibernate_unique_key</param>
> <param name="column">next_hi</param>
> <param name="max_lo">1</param>
> </generator>
> </id>
> <property name="Name" type="System.String" />
>
> <many-to-one name="Parent" class="TestNHJoin.Parent, TestNHJoin">
> <column name="ParentId" not-null="false" />
> </many-to-one>
>
> </class>
>
>
> Simple test:
> public void SaveParent()
> {
>
> using (ISession session = _factory.OpenSession())
> {
> Parent parent;
> Association association1 = new Association();
> association1.Name = "Assoc1";
> Association association2 = new Association();
> association2.Name = "Assoc2";
>
> parent = new Parent();
> parent.Name = "Test";
>
> ParentVersion version1 = new ParentVersion();
> version1.Address = "1st Address";
> version1.Parent = parent;
> version1.Associations.Add(association1);
> version1.Associations.Add(association2);
> parent.Versions.Add(version1);
>
> session.Save(parent);
> session.Flush();
> }
> ISession session = _factory.OpenSession();
> Parent parent = session.CreateCriteria(typeof(Parent))
> .CreateAlias("Versions", "version", JoinType.LeftOuterJoin)
> .CreateAlias("version.Associations", "association",
> JoinType.LeftOuterJoin)
> .SetResultTransformer(new
> DistinctRootEntityResultTransformer())
> .Add(Restrictions.IdEq(id))
> .UniqueResult<Parent>();
>
> Assert.AreEqual(1, parent.Versions.Count);
> }
>
>
> >
>
--
Ken Egozi.
http://www.kenegozi.com/blog
http://www.musicglue.com
http://www.castleproject.org
http://www.gotfriends.co.il
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---