This applies to NHibernate 1.2.1.4000.
Is there some simple example code with a working declaration of a NHibernate.Mapping.Attributes.Query attribute? I've only gotten named queries to work if I put the equivalent XML in an hbm.xml file. I've also tried the RawXML attribute without success.
For RawXML I can't deposit the xml in the correct location in the mapping file (it should be a child of hibernate-mapping). No matter which value I set for the After property of RawXMLAttribute, the rawxml is always streamed within the <class> element.
If I use the Query attribute I can't get the default HbmSerializer to output any content related to the query. The QueryAttribute can only decorate a property or field, so even if it were written out, with the code I have examinied I'm guessing (I know, a bad idea) it would still be written inside the class element instead of being written as a direct descendant of the hibernate-mapping element.
Here's a code excerpt with both ways conditionally compiled:
Code:
#define UseRawXML
...
using NHMA = NHibernate.Mapping.Attributes;
namespace PersistenceTestObjects
{
[NHMA.Class]
public class TestClassToPersist : TestObjectBase
{
public TestClassToPersist() { } // for nHibernate
public TestClassToPersist(string testString) { this.testString = testString; }
private string testString = "test string";
/// <summary>
/// a simple property
/// </summary>
[NHMA.Property(1)]
// so I've created an xml file NamedQueries.hbm.xml for testing
#if UseRawXML
[NHMA.RawXml(Content = @"
<query name=""TestClassToPersistNamedSelectQueryForSingleResult2""><![CDATA[
from TestClassToPersist where ID= :idValue
]]>
</query>
")]
#elif UseQueryAttribute
// although this passes attribute validation, no xml is generated
[NHMA.Query(
Name = "TestClassToPersistNamedSelectQuery",
Content = "from TestClassToPersist where TestString = :propertyvalue"
)
]
#endif
public virtual string TestString
{
get { return testString; }
set { testString = value; }
}
...
}
}
With the code above, the following xml file is generated:
Code:
<?xml version="1.0" encoding="utf-8"?>
<!--Generated by NHibernate.Mapping.Attributes on 2008-02-07 10:14:26Z.-->
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="PersistenceTestObjects.TestClassToPersist, PersistenceTestObjects">
<!---->
<query name="TestClassToPersistNamedSelectQueryForSingleResult2"><![CDATA[
from TestClassToPersist where ID= :idValue
]]>
</query>
<id name="ID" unsaved-value="null">
<generator class="native" />
</id>
<version name="Version" unsaved-value="0" />
<property name="TestString" />
</class>
</hibernate-mapping>
Observe that the query xml is in the wrong place, it should not be contained within the class element. If I move the query element after the closing class tag and run the tests from there everything's ok.
Using the After property of the RawXMLAttribute like so:
Code:
...
[NHMA.RawXml(After=typeof(NHMA.ClassAttribute), Content = @"
<query name=""TestClassToPersistNamedSelectQueryForSingleResult""><![CDATA[
from TestClassToPersist where ID= :idValue
]]>
</query>
")]
...
prevents the query xml element from being generated at all. I've poked in the source code and played around enough to know that even if the query element were generated it would end up in the same place.
I tried to play around with a minor source code change (adding System.AttributeTargets.Class to the or'ed list of AttributeUsage targets in QueryAttribute), so that I could put a Query under a HibernateMappingAttribute above the class declaration like so:
Code:
[NHMA.HibernateMapping(0)]
[NHMA.Query(1,
Name = "TestClassToPersistNamedSelectQuery",
Content = "from TestClassToPersist where TestString = :propertyvalue"
)
]
[NHMA.Class(2)]
public class TestClassToPersist : TestObjectBase
{ ...
but that didn't help. My motivation for hope was, in the NHibernate file HbmWriter.cs, there is a method: (line 1862):
public virtual void WriteHibernateMapping(System.Xml.XmlWriter writer, System.Type type)
that looks like it would process a QueryAttribute (line 1938) residing under the HibernateMappingAttribute, but that method is not called when I call NHibernate.Mapping.Attributes.HbmSerializer.Default.Serialize(filestream, type).
So I'm stuck.