From: <aye...@us...> - 2010-01-06 21:39:32
|
Revision: 4910 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4910&view=rev Author: ayenderahien Date: 2010-01-06 21:39:25 +0000 (Wed, 06 Jan 2010) Log Message: ----------- Fixing NH 2044 & NH 2045 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Type/AbstractCharType.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/DomainClass.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/SampleTest.cs Modified: trunk/nhibernate/src/NHibernate/Type/AbstractCharType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/AbstractCharType.cs 2010-01-06 21:35:19 UTC (rev 4909) +++ trunk/nhibernate/src/NHibernate/Type/AbstractCharType.cs 2010-01-06 21:39:25 UTC (rev 4910) @@ -48,7 +48,7 @@ public override void Set(IDbCommand cmd, object value, int index) { - ((IDataParameter)cmd.Parameters[index]).Value = (char)value; + ((IDataParameter)cmd.Parameters[index]).Value = Convert.ToChar(value); } public override string ObjectToSQLString(object value, Dialect.Dialect dialect) Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/DomainClass.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/DomainClass.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/DomainClass.cs 2010-01-06 21:39:25 UTC (rev 4910) @@ -0,0 +1,22 @@ + + +namespace NHibernate.Test.NHSpecificTest.NH2044 +{ + public class DomainClass + { + private char symbol; + private int id; + + public int Id + { + get { return id; } + set { id = value; } + } + + public char Symbol + { + get { return symbol; } + set { symbol = value; } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/Mappings.hbm.xml 2010-01-06 21:39:25 UTC (rev 4910) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2044" default-access="field.camelcase" + default-lazy="false"> + <class name="DomainClass"> + <id name="Id"> + <generator class="assigned" /> + </id> + <property name="Symbol" type="Char"/> + </class> +</hibernate-mapping> \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/SampleTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/SampleTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2044/SampleTest.cs 2010-01-06 21:39:25 UTC (rev 4910) @@ -0,0 +1,52 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Text; +using NHibernate.Dialect; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2044 +{ + [TestFixture] + public class SampleTest : BugTestCase + { + protected override void OnSetUp() + { + base.OnSetUp(); + using (ISession session = this.OpenSession()) + { + DomainClass entity = new DomainClass(); + entity.Id = 1; + entity.Symbol = 'S'; + session.Save(entity); + session.Flush(); + } + } + + protected override void OnTearDown() + { + base.OnTearDown(); + using (ISession session = this.OpenSession()) + { + string hql = "from DomainClass"; + session.Delete(hql); + session.Flush(); + } + } + + + [Test] + public void IgnoreCaseShouldWorkWithCharCorrectly() + { + using (ISession session = this.OpenSession()) + { + ICriteria criteria = session.CreateCriteria(typeof(DomainClass), "domain"); + criteria.Add(NHibernate.Criterion.Expression.Eq("Symbol", 's').IgnoreCase()); + IList<DomainClass> list = criteria.List<DomainClass>(); + + Assert.AreEqual(1, list.Count); + + } + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-06 21:35:19 UTC (rev 4909) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-06 21:39:25 UTC (rev 4910) @@ -658,6 +658,8 @@ <Compile Include="NHSpecificTest\NH1938\Model.cs" /> <Compile Include="NHSpecificTest\NH1939\AuxType.cs" /> <Compile Include="NHSpecificTest\NH1939\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2044\DomainClass.cs" /> + <Compile Include="NHSpecificTest\NH2044\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2055\AuxType.cs" /> <Compile Include="NHSpecificTest\NH2055\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2057\Fixture.cs" /> @@ -2098,6 +2100,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2044\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2030\Mappings.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\Patient.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2055\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-06 21:41:25
|
Revision: 4911 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4911&view=rev Author: ayenderahien Date: 2010-01-06 21:41:19 +0000 (Wed, 06 Jan 2010) Log Message: ----------- Adding default ctors - per NH-2021 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/ADOException.cs trunk/nhibernate/src/NHibernate/Exceptions/GenericADOException.cs Modified: trunk/nhibernate/src/NHibernate/ADOException.cs =================================================================== --- trunk/nhibernate/src/NHibernate/ADOException.cs 2010-01-06 21:39:25 UTC (rev 4910) +++ trunk/nhibernate/src/NHibernate/ADOException.cs 2010-01-06 21:41:19 UTC (rev 4911) @@ -17,6 +17,10 @@ { private readonly string sql; + public ADOException() + { + + } /// <summary> /// Initializes a new instance of the <see cref="ADOException"/> class. /// </summary> Modified: trunk/nhibernate/src/NHibernate/Exceptions/GenericADOException.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Exceptions/GenericADOException.cs 2010-01-06 21:39:25 UTC (rev 4910) +++ trunk/nhibernate/src/NHibernate/Exceptions/GenericADOException.cs 2010-01-06 21:41:19 UTC (rev 4911) @@ -7,6 +7,10 @@ [Serializable] public class GenericADOException : ADOException { + public GenericADOException() + { + + } public GenericADOException(SerializationInfo info, StreamingContext context) : base(info, context) { } public GenericADOException(string message, Exception innerException, string sql) : base(message, innerException, sql) { } public GenericADOException(string message, Exception innerException) : base(message, innerException) { } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-06 22:33:08
|
Revision: 4913 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4913&view=rev Author: ayenderahien Date: 2010-01-06 22:32:59 +0000 (Wed, 06 Jan 2010) Log Message: ----------- NH1978 - NH will now generate proper aliases for legacy tables that starts with numbers NH-1248 - Subqueries.IsNull Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate/Util/StringHelper.cs trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate/Criterion/NullSubqueryExpression.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/AliasTest.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Employee.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/_401k.cs Added: trunk/nhibernate/src/NHibernate/Criterion/NullSubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/NullSubqueryExpression.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/Criterion/NullSubqueryExpression.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -0,0 +1,19 @@ +using System; +using NHibernate.SqlCommand; + +namespace NHibernate.Criterion +{ + [Serializable] + public class NullSubqueryExpression : SubqueryExpression + { + protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery outerQuery) + { + return SqlString.Empty; + } + + internal NullSubqueryExpression(String quantifier, DetachedCriteria dc) + : base(null, quantifier, dc, false) + { + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2010-01-06 22:11:57 UTC (rev 4912) +++ trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -318,5 +318,14 @@ return Subqueries.NotExists(detachedQuery.DetachedCriteria); } + public static AbstractCriterion IsNull(DetachedCriteria dc) + { + return new NullSubqueryExpression("IS NULL", dc); + } + + public static AbstractCriterion IsNotNull(DetachedCriteria dc) + { + return new NullSubqueryExpression("IS NOT NULL", dc); + } } } Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2010-01-06 22:11:57 UTC (rev 4912) +++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -14,17 +14,25 @@ { private readonly CriteriaImpl criteriaImpl; private readonly String quantifier; - private readonly String op; + private readonly bool prefixOp; + private readonly String op; private QueryParameters parameters; private IType[] types; [NonSerialized] private CriteriaQueryTranslator innerQuery; - protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) + protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) + :this(op, quantifier, dc, true) + { + + } + + protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc, bool prefixOp) { criteriaImpl = dc.GetCriteriaImpl(); this.quantifier = quantifier; - this.op = op; + this.prefixOp = prefixOp; + this.op = op; } public IType[] GetTypes() @@ -68,16 +76,27 @@ buf.Add(" ").Add(op).Add(" "); } - if (quantifier != null) + if (quantifier != null && prefixOp) { buf.Add(quantifier).Add(" "); } - return buf.Add("(").Add(sql).Add(")").ToSqlString(); + + buf.Add("(").Add(sql).Add(")"); + + if(quantifier!=null && prefixOp==false) + { + buf.Add(" ").Add(quantifier); + } + + return buf.ToSqlString(); } public override string ToString() { - return string.Format("{0} {1} ({2})", op, quantifier, criteriaImpl); + if(prefixOp) + return string.Format("{0} {1} ({2})", op, quantifier, criteriaImpl); + return string.Format("{0} ({1}) {2}", op, criteriaImpl, quantifier); + } public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery) Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-01-06 22:11:57 UTC (rev 4912) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-01-06 22:32:59 UTC (rev 4913) @@ -579,6 +579,7 @@ <Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" /> <Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" /> + <Compile Include="Criterion\NullSubqueryExpression.cs" /> <Compile Include="Criterion\ProjectionsExtensions.cs" /> <Compile Include="Dialect\MsSql2008Dialect.cs" /> <Compile Include="Dialect\InformixDialect0940.cs" /> Modified: trunk/nhibernate/src/NHibernate/Util/StringHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Util/StringHelper.cs 2010-01-06 22:11:57 UTC (rev 4912) +++ trunk/nhibernate/src/NHibernate/Util/StringHelper.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -620,10 +620,11 @@ { return result + "x"; //ick! } - else + if(char.IsLetter(result[0]) || '_' == result[0]) { return result; } + return "alias_" + result; } public static string MoveAndToBeginning(string filter) Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-01-06 22:11:57 UTC (rev 4912) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/CriteriaQueryTest.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -127,6 +127,33 @@ } } + [Test] + public void TestSubcriteriaBeingNull() + { + ISession session = OpenSession(); + ITransaction t = session.BeginTransaction(); + + Course hibernateCourse = new Course(); + hibernateCourse.CourseCode = "HIB"; + hibernateCourse.Description = "Hibernate Training"; + session.Save(hibernateCourse); + + DetachedCriteria subcriteria = DetachedCriteria.For<Enrolment>("e"); + subcriteria.Add(Expression.EqProperty("e.CourseCode", "c.CourseCode")); + subcriteria.SetProjection(Projections.Avg("Semester")); + + DetachedCriteria criteria = DetachedCriteria.For<Course>("c"); + criteria.SetProjection(Projections.Count("id")); + criteria.Add(Expression.Or(Subqueries.Le(5, subcriteria), Subqueries.IsNull(subcriteria))); + + object o = criteria.GetExecutableCriteria(session).UniqueResult(); + Assert.AreEqual(1, o); + + session.Delete(hibernateCourse); + t.Commit(); + session.Close(); + } + [Test] public void Subselect() { Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/AliasTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/AliasTest.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/AliasTest.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -0,0 +1,25 @@ +using NHibernate.Cfg; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1978 +{ + [TestFixture] + public class AliasTest : BugTestCase + { + [Test] + public void ShouldReturnPlanFromEmployee() + { + using(var s = OpenSession()) + using (var trans = s.BeginTransaction()) + { + var plan = new _401k {PlanName = "test"}; + s.Save(plan); + s.Refresh(plan); + var emp = new Employee {EmpName = "name", PlanParent = plan}; + s.Save(emp); + + trans.Rollback(); + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Employee.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Employee.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Employee.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -0,0 +1,12 @@ +namespace NHibernate.Test.NHSpecificTest.NH1978 +{ + /// <summary> + /// Category object for NHibernate mapped table 'Categories'. + /// </summary> + public class Employee + { + public virtual int ID { get; set; } + public virtual string EmpName { get; set; } + public virtual _401k PlanParent { get; set; } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/Mappings.hbm.xml 2010-01-06 22:32:59 UTC (rev 4913) @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping + namespace="NHibernate.Test.NHSpecificTest.NH1978" + assembly="NHibernate.Test" + xmlns="urn:nhibernate-mapping-2.2"> + <class name="Employee" lazy="true" table="Employee"> + <id name="ID" type="Int32" unsaved-value="0"> + <generator class="native" /> + </id> + <property name="EmpName" type="String"> + </property> + <many-to-one name="PlanParent" class="_401k" > + <column name="Plan401kID" sql-type="int" not-null="false" /> + </many-to-one> + </class> + <class name="_401k" lazy="true" table="[401k]"> + <id name="ID" type="Int32" unsaved-value="0"> + <generator class="native" /> + </id> + <property name="PlanName" type="String"> + </property> + <bag name="Employees" inverse="true" lazy="true" cascade="all-delete-orphan" > + <key column="Plan401kID" /> + <one-to-many class="Employee"/> + </bag> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/_401k.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/_401k.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1978/_401k.cs 2010-01-06 22:32:59 UTC (rev 4913) @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH1978 +{ + /// <summary> + /// Product object for NHibernate mapped table 'Products'. + /// </summary> + public class _401k + { + public virtual int ID { get; set; } + public virtual string PlanName { get; set; } + public virtual IList<Employee> Employees { get; set; } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-06 22:11:57 UTC (rev 4912) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-06 22:32:59 UTC (rev 4913) @@ -658,6 +658,9 @@ <Compile Include="NHSpecificTest\NH1938\Model.cs" /> <Compile Include="NHSpecificTest\NH1939\AuxType.cs" /> <Compile Include="NHSpecificTest\NH1939\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1978\AliasTest.cs" /> + <Compile Include="NHSpecificTest\NH1978\Employee.cs" /> + <Compile Include="NHSpecificTest\NH1978\_401k.cs" /> <Compile Include="NHSpecificTest\NH2044\DomainClass.cs" /> <Compile Include="NHSpecificTest\NH2044\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2055\AuxType.cs" /> @@ -2100,6 +2103,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1978\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2044\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2030\Mappings.hbm.xml" /> <EmbeddedResource Include="Linq\Mappings\Patient.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-08 10:09:54
|
Revision: 4915 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4915&view=rev Author: ayenderahien Date: 2010-01-08 10:09:47 +0000 (Fri, 08 Jan 2010) Log Message: ----------- Explicitly set parameter sizes - prevent query cache plan per each actual parameter size Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Driver/OdbcDriver.cs trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs trunk/nhibernate/src/NHibernate.Test/SqlTest/Identity/MsSQL/MSSQLIdentityInsertWithStoredProcsTest.cs Modified: trunk/nhibernate/src/NHibernate/Driver/OdbcDriver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/OdbcDriver.cs 2010-01-08 06:57:28 UTC (rev 4914) +++ trunk/nhibernate/src/NHibernate/Driver/OdbcDriver.cs 2010-01-08 10:09:47 UTC (rev 4915) @@ -69,7 +69,7 @@ public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) { IDbCommand command = base.GenerateCommand(type, sqlString, parameterTypes); - if (IsPrepareSqlEnabled) + //if (IsPrepareSqlEnabled) { SetParameterSizes(command.Parameters, parameterTypes); } Modified: trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs 2010-01-08 06:57:28 UTC (rev 4914) +++ trunk/nhibernate/src/NHibernate/Driver/SqlClientDriver.cs 2010-01-08 10:09:47 UTC (rev 4915) @@ -153,7 +153,7 @@ public override IDbCommand GenerateCommand(CommandType type, SqlString sqlString, SqlType[] parameterTypes) { IDbCommand command = base.GenerateCommand(type, sqlString, parameterTypes); - if (IsPrepareSqlEnabled) + //if (IsPrepareSqlEnabled) { SetParameterSizes(command.Parameters, parameterTypes); } Modified: trunk/nhibernate/src/NHibernate.Test/SqlTest/Identity/MsSQL/MSSQLIdentityInsertWithStoredProcsTest.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/SqlTest/Identity/MsSQL/MSSQLIdentityInsertWithStoredProcsTest.cs 2010-01-08 06:57:28 UTC (rev 4914) +++ trunk/nhibernate/src/NHibernate.Test/SqlTest/Identity/MsSQL/MSSQLIdentityInsertWithStoredProcsTest.cs 2010-01-08 10:09:47 UTC (rev 4915) @@ -14,7 +14,7 @@ protected override string GetExpectedInsertOrgLogStatement(string orgName) { - return string.Format("exec nh_organization_native_id_insert @p0;@p0 = '{0}' [Type: String ({1})]", orgName, orgName.Length); + return string.Format("exec nh_organization_native_id_insert @p0;@p0 = '{0}' [Type: String (4000)]", orgName); } protected override IList Mappings This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-01-10 19:01:49
|
Revision: 4916 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4916&view=rev Author: ricbrown Date: 2010-01-10 19:01:42 +0000 (Sun, 10 Jan 2010) Log Message: ----------- Fix NH-1989 (Future queries not using second level cache) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs trunk/nhibernate/src/NHibernate/Impl/DelayedEnumerator.cs trunk/nhibernate/src/NHibernate/Impl/FutureBatch.cs trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs trunk/nhibernate/src/NHibernate/Impl/FutureQueryBatch.cs trunk/nhibernate/src/NHibernate/Impl/FutureValue.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Model.cs Modified: trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate/Impl/AbstractQueryImpl.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -56,6 +56,16 @@ this.parameterMetadata = parameterMetadata; } + public bool Cacheable + { + get { return cacheable; } + } + + public string CacheRegion + { + get { return cacheRegion; } + } + public bool HasNamedParameters { get { return parameterMetadata.NamedParameterNames.Count > 0; } Modified: trunk/nhibernate/src/NHibernate/Impl/DelayedEnumerator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/DelayedEnumerator.cs 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate/Impl/DelayedEnumerator.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -5,7 +5,7 @@ { internal class DelayedEnumerator<T> : IEnumerable<T> { - public delegate IList<T> GetResult(); + public delegate IEnumerable<T> GetResult(); private readonly GetResult result; Modified: trunk/nhibernate/src/NHibernate/Impl/FutureBatch.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/FutureBatch.cs 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate/Impl/FutureBatch.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Generic; +using System.Linq; namespace NHibernate.Impl { @@ -9,6 +10,8 @@ private readonly IList<System.Type> resultTypes = new List<System.Type>(); private int index; private IList results; + private bool isCacheable = true; + private string cacheRegion; protected readonly SessionImpl session; @@ -31,9 +34,16 @@ public void Add<TResult>(TQueryApproach query) { + if (queries.Count == 0) + { + cacheRegion = CacheRegion(query); + } + queries.Add(query); resultTypes.Add(typeof(TResult)); index = queries.Count - 1; + isCacheable = isCacheable && IsQueryCacheable(query); + isCacheable = isCacheable && (cacheRegion == CacheRegion(query)); } public void Add(TQueryApproach query) @@ -55,7 +65,7 @@ private void GetResults() { - var multiApproach = CreateMultiApproach(); + var multiApproach = CreateMultiApproach(isCacheable, cacheRegion); for (int i = 0; i < queries.Count; i++) { AddTo(multiApproach, queries[i], resultTypes[i]); @@ -64,14 +74,16 @@ ClearCurrentFutureBatch(); } - private IList<TResult> GetCurrentResult<TResult>(int currentIndex) + private IEnumerable<TResult> GetCurrentResult<TResult>(int currentIndex) { - return (IList<TResult>)Results[currentIndex]; + return ((IList)Results[currentIndex]).Cast<TResult>(); } - protected abstract TMultiApproach CreateMultiApproach(); + protected abstract TMultiApproach CreateMultiApproach(bool isCacheable, string cacheRegion); protected abstract void AddTo(TMultiApproach multiApproach, TQueryApproach query, System.Type resultType); protected abstract IList GetResultsFrom(TMultiApproach multiApproach); protected abstract void ClearCurrentFutureBatch(); + protected abstract bool IsQueryCacheable(TQueryApproach query); + protected abstract string CacheRegion(TQueryApproach query); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate/Impl/FutureCriteriaBatch.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -6,9 +6,12 @@ { public FutureCriteriaBatch(SessionImpl session) : base(session) {} - protected override IMultiCriteria CreateMultiApproach() + protected override IMultiCriteria CreateMultiApproach(bool isCacheable, string cacheRegion) { - return session.CreateMultiCriteria(); + return + session.CreateMultiCriteria() + .SetCacheable(isCacheable) + .SetCacheRegion(cacheRegion); } protected override void AddTo(IMultiCriteria multiApproach, ICriteria query, System.Type resultType) @@ -25,5 +28,15 @@ { session.FutureCriteriaBatch = null; } + + protected override bool IsQueryCacheable(ICriteria query) + { + return ((CriteriaImpl)query).Cacheable; + } + + protected override string CacheRegion(ICriteria query) + { + return ((CriteriaImpl)query).CacheRegion; + } } } Modified: trunk/nhibernate/src/NHibernate/Impl/FutureQueryBatch.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/FutureQueryBatch.cs 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate/Impl/FutureQueryBatch.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -6,9 +6,12 @@ { public FutureQueryBatch(SessionImpl session) : base(session) {} - protected override IMultiQuery CreateMultiApproach() + protected override IMultiQuery CreateMultiApproach(bool isCacheable, string cacheRegion) { - return session.CreateMultiQuery(); + return + session.CreateMultiQuery() + .SetCacheable(isCacheable) + .SetCacheRegion(cacheRegion); } protected override void AddTo(IMultiQuery multiApproach, IQuery query, System.Type resultType) @@ -25,5 +28,15 @@ { session.FutureQueryBatch = null; } + + protected override bool IsQueryCacheable(IQuery query) + { + return ((AbstractQueryImpl)query).Cacheable; + } + + protected override string CacheRegion(IQuery query) + { + return ((AbstractQueryImpl)query).CacheRegion; + } } } Modified: trunk/nhibernate/src/NHibernate/Impl/FutureValue.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/FutureValue.cs 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate/Impl/FutureValue.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -5,7 +5,7 @@ { internal class FutureValue<T> : IFutureValue<T> { - public delegate IList<T> GetResult(); + public delegate IEnumerable<T> GetResult(); private readonly GetResult getResult; @@ -19,13 +19,14 @@ get { var result = getResult(); + var enumerator = result.GetEnumerator(); - if (result.Count == 0) - { + if (!enumerator.MoveNext()) + { return default(T); } - return result[0]; + return enumerator.Current; } } } Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Fixture.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -0,0 +1,274 @@ +using System.Data; + +using NUnit.Framework; + +using NHibernate.Cache; +using NHibernate.Cfg; +using NHibernate.Criterion; +using NHibernate.Engine; + +using System.Collections.Generic; +using System.Linq; + +namespace NHibernate.Test.NHSpecificTest.NH1989 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + cfg.Properties[Environment.CacheProvider] = typeof(HashtableCacheProvider).AssemblyQualifiedName; + cfg.Properties[Environment.UseQueryCache] = "true"; + sessions = (ISessionFactoryImplementor)cfg.BuildSessionFactory(); + } + + protected override void OnTearDown() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + s.Delete("from User"); + tx.Commit(); + } + } + + private static void DeleteObjectsOutsideCache(ISession s) + { + using (IDbCommand cmd = s.Connection.CreateCommand()) + { + cmd.CommandText = "DELETE FROM UserTable"; + cmd.ExecuteNonQuery(); + } + } + + [Test] + public void SecondLevelCacheWithSingleCacheableFuture() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + User user = new User() { Name="test" }; + s.Save(user); + tx.Commit(); + } + + using (ISession s = OpenSession()) + { + // Query results should be cached + User user = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .FutureValue<User>() + .Value; + + Assert.That(user, Is.Not.Null); + + DeleteObjectsOutsideCache(s); + } + + using (ISession s = OpenSession()) + { + User user = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .FutureValue<User>() + .Value; + + Assert.That(user, Is.Not.Null, + "entity not retrieved from cache"); + } + } + + [Test] + public void SecondLevelCacheWithDifferentRegionsFuture() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + User user = new User() { Name="test" }; + s.Save(user); + tx.Commit(); + } + + using (ISession s = OpenSession()) + { + // Query results should be cached + User user = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .SetCacheRegion("region1") + .FutureValue<User>() + .Value; + + Assert.That(user, Is.Not.Null); + + DeleteObjectsOutsideCache(s); + } + + using (ISession s = OpenSession()) + { + User user = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .SetCacheRegion("region2") + .FutureValue<User>() + .Value; + + Assert.That(user, Is.Null, + "entity from different region should not be retrieved"); + } + } + + [Test] + public void SecondLevelCacheWithMixedCacheableAndNonCacheableFuture() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + User user = new User() { Name="test" }; + s.Save(user); + tx.Commit(); + } + + using (ISession s = OpenSession()) + { + // cacheable Future, not evaluated yet + IFutureValue<User> userFuture = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .FutureValue<User>(); + + // non cacheable Future causes batch to be non-cacheable + int count = + s.CreateCriteria<User>() + .SetProjection(Projections.RowCount()) + .FutureValue<int>() + .Value; + + Assert.That(userFuture.Value, Is.Not.Null); + Assert.That(count, Is.EqualTo(1)); + + DeleteObjectsOutsideCache(s); + } + + using (ISession s = OpenSession()) + { + IFutureValue<User> userFuture = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .FutureValue<User>(); + + int count = + s.CreateCriteria<User>() + .SetProjection(Projections.RowCount()) + .FutureValue<int>() + .Value; + + Assert.That(userFuture.Value, Is.Null, + "query results should not come from cache"); + } + } + + [Test] + public void SecondLevelCacheWithMixedCacheRegionsFuture() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + User user = new User() { Name="test" }; + s.Save(user); + tx.Commit(); + } + + using (ISession s = OpenSession()) + { + // cacheable Future, not evaluated yet + IFutureValue<User> userFuture = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .SetCacheRegion("region1") + .FutureValue<User>(); + + // different cache-region causes batch to be non-cacheable + int count = + s.CreateCriteria<User>() + .SetProjection(Projections.RowCount()) + .SetCacheable(true) + .SetCacheRegion("region2") + .FutureValue<int>() + .Value; + + Assert.That(userFuture.Value, Is.Not.Null); + Assert.That(count, Is.EqualTo(1)); + + DeleteObjectsOutsideCache(s); + } + + using (ISession s = OpenSession()) + { + IFutureValue<User> userFuture = + s.CreateCriteria<User>() + .Add(Restrictions.NaturalId().Set("Name", "test")) + .SetCacheable(true) + .SetCacheRegion("region1") + .FutureValue<User>(); + + int count = + s.CreateCriteria<User>() + .SetProjection(Projections.RowCount()) + .SetCacheable(true) + .SetCacheRegion("region2") + .FutureValue<int>() + .Value; + + Assert.That(userFuture.Value, Is.Null, + "query results should not come from cache"); + } + } + + [Test] + public void SecondLevelCacheWithSingleCacheableQueryFuture() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + User user = new User() { Name="test" }; + s.Save(user); + tx.Commit(); + } + + using (ISession s = OpenSession()) + { + // Query results should be cached + User user = + s.CreateQuery("from User u where u.Name='test'") + .SetCacheable(true) + .FutureValue<User>() + .Value; + + Assert.That(user, Is.Not.Null); + + DeleteObjectsOutsideCache(s); + } + + using (ISession s = OpenSession()) + { + User user = + s.CreateQuery("from User u where u.Name='test'") + .SetCacheable(true) + .FutureValue<User>() + .Value; + + Assert.That(user, Is.Not.Null, + "entity not retrieved from cache"); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Mappings.hbm.xml 2010-01-10 19:01:42 UTC (rev 4916) @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH1989" + assembly="NHibernate.Test"> + + <class name="User" table="UserTable"> + <cache usage="read-write"/> + <id name="Id"> + <generator class="guid.comb"/> + </id> + <natural-id> + <property name="Name" /> + </natural-id> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1989/Model.cs 2010-01-10 19:01:42 UTC (rev 4916) @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH1989 +{ + public class User + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-08 10:09:47 UTC (rev 4915) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-10 19:01:42 UTC (rev 4916) @@ -661,6 +661,8 @@ <Compile Include="NHSpecificTest\NH1978\AliasTest.cs" /> <Compile Include="NHSpecificTest\NH1978\Employee.cs" /> <Compile Include="NHSpecificTest\NH1978\_401k.cs" /> + <Compile Include="NHSpecificTest\NH1989\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1989\Model.cs" /> <Compile Include="NHSpecificTest\NH2044\DomainClass.cs" /> <Compile Include="NHSpecificTest\NH2044\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2055\AuxType.cs" /> @@ -2103,6 +2105,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1989\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1978\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2044\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2030\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-13 15:56:50
|
Revision: 4917 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4917&view=rev Author: ayenderahien Date: 2010-01-13 15:56:35 +0000 (Wed, 13 Jan 2010) Log Message: ----------- Fixing NH-2065 - better error message on reassociation of dirty collection Fixing NH-2064 - changed exception for filters definition without usage to lor.Error Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs trunk/nhibernate/src/NHibernate/Event/Default/OnLockVisitor.cs trunk/nhibernate/src/NHibernate.Test/FilterTest/ConfigFixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Model.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2010-01-10 19:01:42 UTC (rev 4916) +++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2010-01-13 15:56:35 UTC (rev 4917) @@ -965,8 +965,7 @@ // if you are going to remove this exception at least add a log.Error // because the usage of filter-def, outside its scope, may cause unexpected behaviour // during queries. - throw new MappingException("filter-def for filter named '" + filterName - + "' was never used to filter classes nor collections."); + log.ErrorFormat("filter-def for filter named '{0}' was never used to filter classes nor collections.\r\nThis may result in unexpected behavior during queries", filterName); } } } Modified: trunk/nhibernate/src/NHibernate/Event/Default/OnLockVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/OnLockVisitor.cs 2010-01-10 19:01:42 UTC (rev 4916) +++ trunk/nhibernate/src/NHibernate/Event/Default/OnLockVisitor.cs 2010-01-13 15:56:35 UTC (rev 4917) @@ -36,14 +36,14 @@ // a "detached" collection that originally belonged to the same entity if (persistentCollection.IsDirty) { - throw new HibernateException("reassociated object has dirty collection"); + throw new HibernateException("reassociated object has dirty collection: " + persistentCollection.Role); } ReattachCollection(persistentCollection, type); } else { // a "detached" collection that belonged to a different entity - throw new HibernateException("reassociated object has dirty collection reference"); + throw new HibernateException("reassociated object has dirty collection reference: " + persistentCollection.Role); } } else @@ -51,7 +51,7 @@ // a collection loaded in the current session // can not possibly be the collection belonging // to the entity passed to update() - throw new HibernateException("reassociated object has dirty collection reference"); + throw new HibernateException("reassociated object has dirty collection reference: " + persistentCollection.Role); } } else Modified: trunk/nhibernate/src/NHibernate.Test/FilterTest/ConfigFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/FilterTest/ConfigFixture.cs 2010-01-10 19:01:42 UTC (rev 4916) +++ trunk/nhibernate/src/NHibernate.Test/FilterTest/ConfigFixture.cs 2010-01-13 15:56:35 UTC (rev 4917) @@ -1,6 +1,11 @@ +using System; using System.Collections.Generic; +using log4net; +using log4net.Appender; +using log4net.Config; using NHibernate.Cfg; using NUnit.Framework; +using System.Linq; namespace NHibernate.Test.FilterTest { @@ -236,9 +241,20 @@ var cfg = GetConfiguration(); cfg.AddXmlString(filterDef); - var e = Assert.Throws<MappingException>(() => cfg.BuildSessionFactory()); - Assert.That(e.Message, Text.StartsWith("filter-def for filter named")); - Assert.That(e.Message, Text.Contains("was never used to filter classes nor collections.")); + var memoryAppender = new MemoryAppender(); + BasicConfigurator.Configure(memoryAppender); + try + { + cfg.BuildSessionFactory(); + + var wholeLog = String.Join("\r\n", memoryAppender.GetEvents().Select(x => x.RenderedMessage).ToArray()); + Assert.That(wholeLog, Text.Contains("filter-def for filter named")); + Assert.That(wholeLog, Text.Contains("was never used to filter classes nor collections.")); + } + finally + { + LogManager.Shutdown(); + } } } } Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Fixture.cs 2010-01-13 15:56:35 UTC (rev 4917) @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Transactions; +using NHibernate.Impl; +using NUnit.Framework; +using NHibernate.Criterion; + +namespace NHibernate.Test.NHSpecificTest.NH2065 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + using (var s = OpenSession()) + using (s.BeginTransaction()) + { + var person = new Person + { + Children = new HashSet<Person>() + }; + s.Save(person); + var child = new Person(); + s.Save(child); + person.Children.Add(child); + + s.Transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + using (s.BeginTransaction()) + { + s.Delete("from Person"); + s.Transaction.Commit(); + } + } + + [Test] + [ExpectedException( + ExpectedException=typeof(HibernateException), + ExpectedMessage="reassociated object has dirty collection: NHibernate.Test.NHSpecificTest.NH2065.Person.Children")] + public void GetGoodErrorForDirtyReassociatedCollection() + { + Person person; + using (var s = OpenSession()) + using (s.BeginTransaction()) + { + person = s.Get<Person>(1); + NHibernateUtil.Initialize(person.Children); + s.Transaction.Commit(); + } + + person.Children.Clear(); + + using (var s = OpenSession()) + using (s.BeginTransaction()) + { + s.Lock(person, LockMode.None); + } + } + + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Mappings.hbm.xml 2010-01-13 15:56:35 UTC (rev 4917) @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2065"> + + <class name="Person"> + <id name="Id"> + <generator class="increment" /> + </id> + <property name="Name"/> + + <set name="Children"> + <key column="ParentId"/> + <one-to-many class="Person"/> + </set> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2065/Model.cs 2010-01-13 15:56:35 UTC (rev 4917) @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2065 +{ + public class Person + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual ICollection<Person> Children { get; set; } + } + +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-10 19:01:42 UTC (rev 4916) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-13 15:56:35 UTC (rev 4917) @@ -692,6 +692,8 @@ <Compile Include="NHSpecificTest\NH2011\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2011\Model.cs" /> <Compile Include="NHSpecificTest\NH2030\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2065\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2065\Model.cs" /> <Compile Include="NHSpecificTest\NH473\Child.cs" /> <Compile Include="NHSpecificTest\NH473\Fixture.cs" /> <Compile Include="NHSpecificTest\NH473\Parent.cs" /> @@ -2105,6 +2107,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2065\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1989\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1978\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2044\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-01-17 19:31:17
|
Revision: 4919 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4919&view=rev Author: ricbrown Date: 2010-01-17 19:31:11 +0000 (Sun, 17 Jan 2010) Log Message: ----------- Fix NH-2009 (Many-to-one fails when using property-ref against a joined property) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs trunk/nhibernate/src/NHibernate/Loader/Entity/EntityJoinWalker.cs trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs trunk/nhibernate/src/NHibernate/Mapping/ForeignKey.cs trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs trunk/nhibernate/src/NHibernate/Persister/Entity/IOuterJoinLoadable.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Model.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate/Cfg/Configuration.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -1137,7 +1137,7 @@ try { - fk.ReferencedTable = referencedClass.Table; + fk.AddReferencedTable(referencedClass); fk.AlignColumns(); } catch (MappingException me) Modified: trunk/nhibernate/src/NHibernate/Loader/Entity/EntityJoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Entity/EntityJoinWalker.cs 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate/Loader/Entity/EntityJoinWalker.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -29,6 +29,14 @@ } /// <summary> + /// Override to use the persister to change the table-alias for columns in join-tables + /// </summary> + protected override string GenerateAliasForColumn(string rootAlias, string column) + { + return Persister.GenerateTableAliasForColumn(rootAlias, column); + } + + /// <summary> /// Disable outer join fetching if this loader obtains an /// upgrade lock mode /// </summary> Modified: trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -667,6 +667,11 @@ return buf.ToSqlString(); } + protected virtual string GenerateAliasForColumn(string rootAlias, string column) + { + return rootAlias; + } + /// <summary> /// Render the where condition for a (batch) load by identifier / collection key /// </summary> @@ -676,7 +681,8 @@ { // if not a composite key, use "foo in (?, ?, ?)" for batching // if no batch, and not a composite key, use "foo = ?" - InFragment inf = new InFragment().SetColumn(alias, columnNames[0]); + string tableAlias = GenerateAliasForColumn(alias, columnNames[0]); + InFragment inf = new InFragment().SetColumn(tableAlias, columnNames[0]); for (int i = 0; i < batchSize; i++) inf.AddValue(Parameter.Placeholder); Modified: trunk/nhibernate/src/NHibernate/Mapping/ForeignKey.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/ForeignKey.cs 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate/Mapping/ForeignKey.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -158,6 +158,18 @@ referencedColumns.Add(column); } + internal void AddReferencedTable(PersistentClass referencedClass) + { + if (referencedColumns.Count > 0) + { + referencedTable = referencedColumns[0].Value.Table; + } + else + { + referencedTable = referencedClass.Table; + } + } + public override string ToString() { if (!IsReferenceToPrimaryKey) Modified: trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -1817,6 +1817,16 @@ } } + public string GenerateTableAliasForColumn(string rootAlias, string column) + { + int propertyIndex = Array.IndexOf(SubclassColumnClosure, column); + + if (propertyIndex < 0) + return rootAlias; + + return GenerateTableAlias(rootAlias, SubclassColumnTableNumberClosure[propertyIndex]); + } + public string GenerateTableAlias(string rootAlias, int tableNumber) { if (tableNumber == 0) Modified: trunk/nhibernate/src/NHibernate/Persister/Entity/IOuterJoinLoadable.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/Entity/IOuterJoinLoadable.cs 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate/Persister/Entity/IOuterJoinLoadable.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -113,5 +113,10 @@ /// Return the alised identifier column names /// </summary> string[] ToIdentifierColumns(string alias); + + /// <summary> + /// Get the table alias used for the supplied column + /// </summary> + string GenerateTableAliasForColumn(string rootAlias, string column); } } \ No newline at end of file Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Fixture.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -0,0 +1,50 @@ +using System; +using System.Collections; +using NHibernate.Criterion; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2009 +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void PropertyRefToJoinedTable() + { + BlogPost savedBlogPost = new BlogPost(); + + using (ISession session = OpenSession()) + { + User user1 = new User(); + user1.FullName = "First User"; + user1.UserName = "User1"; + session.Save(user1); + + User user2 = new User(); + user2.FullName = "Second User"; + user2.UserName = "User2"; + session.Save(user2); + + savedBlogPost.Title = "Post 1"; + savedBlogPost.Poster = user1; + session.Save(savedBlogPost); + + session.Flush(); + session.Clear(); + } + + using (ISession session = OpenSession()) + { + var user = session.Get<BlogPost>(savedBlogPost.ID); + } + + using (ISession session = OpenSession()) + using (ITransaction tx = session.BeginTransaction()) + { + session.Delete("from User"); + session.Delete("from BlogPost"); + tx.Commit(); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Mappings.hbm.xml 2010-01-17 19:31:11 UTC (rev 4919) @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH2009" + assembly="NHibernate.Test"> + + <class name="BlogPost" table="blogpost_table"> + <id name="ID" column="blogpost_id"> + <generator class="native"/> + </id> + <property name="Title" column="blogpost_title"/> + <many-to-one name="Poster" column="poster_id" property-ref="UserName" /> + </class> + + <class name="User" table="user_table"> + <id name="ID" column="user_id"> + <generator class="native"/> + </id> + <property name="FullName" column="user_fullname" unique="true"/> + <join table="ADUser"> + <key column="user_id"/> + <property name="UserName" column="aduser_username" unique="true"/> + </join> + </class> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2009/Model.cs 2010-01-17 19:31:11 UTC (rev 4919) @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH2009 +{ + public class BlogPost + { + public virtual int ID { get; set; } + public virtual string Title { get; set; } + public virtual User Poster { get; set; } + } + + public class User + { + public virtual int ID { get; set; } + public virtual string FullName { get; set; } + public virtual string UserName { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-13 16:03:54 UTC (rev 4918) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-17 19:31:11 UTC (rev 4919) @@ -663,6 +663,8 @@ <Compile Include="NHSpecificTest\NH1978\_401k.cs" /> <Compile Include="NHSpecificTest\NH1989\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1989\Model.cs" /> + <Compile Include="NHSpecificTest\NH2009\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2009\Model.cs" /> <Compile Include="NHSpecificTest\NH2044\DomainClass.cs" /> <Compile Include="NHSpecificTest\NH2044\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2055\AuxType.cs" /> @@ -2108,6 +2110,7 @@ <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> <EmbeddedResource Include="NHSpecificTest\NH2065\Mappings.hbm.xml" /> + <EmbeddedResource Include="NHSpecificTest\NH2009\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1989\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1978\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2044\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-01-19 12:53:27
|
Revision: 4921 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4921&view=rev Author: ricbrown Date: 2010-01-19 12:53:21 +0000 (Tue, 19 Jan 2010) Log Message: ----------- Improvement to projection list syntax in QueryOver. (Thanks to maciejk for suggesting improvement in NH-Forge blog reply) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2010-01-19 10:31:20 UTC (rev 4920) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverProjectionBuilder.cs 2010-01-19 12:53:21 UTC (rev 4921) @@ -9,18 +9,14 @@ namespace NHibernate.Criterion.Lambda { - public class QueryOverProjectionBuilder<TReturn, TRoot, TSubType> + public class QueryOverProjectionBuilder<T> { - private TReturn fluentReturn; - private IQueryOver<TRoot,TSubType> criteria; private ProjectionList projectionList; private IProjection lastProjection = null; - public QueryOverProjectionBuilder(TReturn fluentReturn, IQueryOver<TRoot,TSubType> criteria) + public QueryOverProjectionBuilder() { - this.fluentReturn = fluentReturn; - this.criteria = criteria; projectionList = Projections.ProjectionList(); } @@ -36,23 +32,19 @@ lastProjection = projection; } - /// <summary> - /// Create the ProjectionList and return to the query - /// </summary> - public TReturn EndSelect + internal ProjectionList ProjectionList { get { AddLastProjection(); - criteria.Select(projectionList); - return fluentReturn; + return projectionList; } } /// <summary> /// Create an alias for the previous projection /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> WithAlias(Expression<Func<object>> alias) + public QueryOverProjectionBuilder<T> WithAlias(Expression<Func<object>> alias) { string aliasContainer = ExpressionProcessor.FindMemberExpression(alias.Body); lastProjection = Projections.Alias(lastProjection, aliasContainer); @@ -62,7 +54,7 @@ /// <summary> /// Select an arbitrary projection /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(IProjection projection) + public QueryOverProjectionBuilder<T> Select(IProjection projection) { PushProjection(projection); return this; @@ -71,7 +63,7 @@ /// <summary> /// A property average value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectAvg(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectAvg(Expression<Func<T, object>> expression) { PushProjection(Projections.Avg(expression)); return this; @@ -80,7 +72,7 @@ /// <summary> /// A property average value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectAvg(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectAvg(Expression<Func<object>> expression) { PushProjection(Projections.Avg(expression)); return this; @@ -89,7 +81,7 @@ /// <summary> /// A property value count /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCount(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectCount(Expression<Func<T, object>> expression) { PushProjection(Projections.Count(expression)); return this; @@ -98,7 +90,7 @@ /// <summary> /// A property value count /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCount(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectCount(Expression<Func<object>> expression) { PushProjection(Projections.Count(expression)); return this; @@ -107,7 +99,7 @@ /// <summary> /// A distinct property value count /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCountDistinct(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectCountDistinct(Expression<Func<T, object>> expression) { PushProjection(Projections.CountDistinct(expression)); return this; @@ -116,7 +108,7 @@ /// <summary> /// A distinct property value count /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectCountDistinct(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectCountDistinct(Expression<Func<object>> expression) { PushProjection(Projections.CountDistinct(expression)); return this; @@ -125,7 +117,7 @@ /// <summary> /// A grouping property value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectGroup(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectGroup(Expression<Func<T, object>> expression) { PushProjection(Projections.Group(expression)); return this; @@ -134,7 +126,7 @@ /// <summary> /// A grouping property value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectGroup(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectGroup(Expression<Func<object>> expression) { PushProjection(Projections.Group(expression)); return this; @@ -143,7 +135,7 @@ /// <summary> /// A property maximum value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMax(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectMax(Expression<Func<T, object>> expression) { PushProjection(Projections.Max(expression)); return this; @@ -152,7 +144,7 @@ /// <summary> /// A property maximum value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMax(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectMax(Expression<Func<object>> expression) { PushProjection(Projections.Max(expression)); return this; @@ -161,7 +153,7 @@ /// <summary> /// A property minimum value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMin(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectMin(Expression<Func<T, object>> expression) { PushProjection(Projections.Min(expression)); return this; @@ -170,7 +162,7 @@ /// <summary> /// A property minimum value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectMin(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectMin(Expression<Func<object>> expression) { PushProjection(Projections.Min(expression)); return this; @@ -179,7 +171,7 @@ /// <summary> /// A projected property value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> Select(Expression<Func<T, object>> expression) { PushProjection(Projections.Property(expression)); return this; @@ -188,13 +180,13 @@ /// <summary> /// A projected property value /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> Select(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> Select(Expression<Func<object>> expression) { PushProjection(Projections.Property(expression)); return this; } - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSubQuery<U>(QueryOver<U> detachedQueryOver) + public QueryOverProjectionBuilder<T> SelectSubQuery<U>(QueryOver<U> detachedQueryOver) { PushProjection(Projections.SubQuery(detachedQueryOver)); return this; @@ -203,7 +195,7 @@ /// <summary> /// A property value sum /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSum(Expression<Func<TSubType, object>> expression) + public QueryOverProjectionBuilder<T> SelectSum(Expression<Func<T, object>> expression) { PushProjection(Projections.Sum(expression)); return this; @@ -212,7 +204,7 @@ /// <summary> /// A property value sum /// </summary> - public QueryOverProjectionBuilder<TReturn, TRoot, TSubType> SelectSum(Expression<Func<object>> expression) + public QueryOverProjectionBuilder<T> SelectSum(Expression<Func<object>> expression) { PushProjection(Projections.Sum(expression)); return this; Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-01-19 10:31:20 UTC (rev 4920) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-01-19 12:53:21 UTC (rev 4921) @@ -264,9 +264,10 @@ return this; } - public QueryOverProjectionBuilder<QueryOver<TRoot,TSubType>, TRoot, TSubType> SelectList + public QueryOver<TRoot, TSubType> Select(Func<QueryOverProjectionBuilder<TSubType>, QueryOverProjectionBuilder<TSubType>> list) { - get { return new QueryOverProjectionBuilder<QueryOver<TRoot,TSubType>, TRoot, TSubType>(this, this); } + criteria.SetProjection(list(new QueryOverProjectionBuilder<TSubType>()).ProjectionList); + return this; } public QueryOverOrderBuilder<TRoot,TSubType> OrderBy(Expression<Func<TSubType, object>> path) @@ -604,8 +605,8 @@ IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Select(params IProjection[] projections) { return Select(projections); } - QueryOverProjectionBuilder<IQueryOver<TRoot,TSubType>, TRoot, TSubType> IQueryOver<TRoot,TSubType>.SelectList - { get { return new QueryOverProjectionBuilder<IQueryOver<TRoot,TSubType>,TRoot,TSubType>(this, this); } } + IQueryOver<TRoot, TSubType> IQueryOver<TRoot, TSubType>.Select(Func<QueryOverProjectionBuilder<TSubType>, QueryOverProjectionBuilder<TSubType>> list) + { return Select(list); } IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.OrderBy(Expression<Func<TSubType, object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-01-19 10:31:20 UTC (rev 4920) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-01-19 12:53:21 UTC (rev 4921) @@ -208,9 +208,9 @@ IQueryOver<TRoot,TSubType> Select(params IProjection[] projections); /// <summary> - /// Create a list of projections inline + /// Create a list of projections using a projection builder /// </summary> - QueryOverProjectionBuilder<IQueryOver<TRoot,TSubType>, TRoot, TSubType> SelectList { get; } + IQueryOver<TRoot, TSubType> Select(Func<QueryOverProjectionBuilder<TSubType>, QueryOverProjectionBuilder<TSubType>> list); /// <summary> /// Add order expressed as a lambda expression Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2010-01-19 10:31:20 UTC (rev 4920) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2010-01-19 12:53:21 UTC (rev 4921) @@ -231,9 +231,7 @@ QueryOver<Child> averageChildAge = QueryOver.Of<Child>() - .SelectList - .SelectAvg(c => c.Age) - .EndSelect; + .Select(p => p.SelectAvg(c => c.Age)); QueryOver<Child> childCountQuery = QueryOver.Of<Child>() @@ -243,11 +241,10 @@ var nameAndChildCount = s.QueryOver<Person>(() => personAlias) .WithSubquery.Where(p => p.Age <= averageChildAge.As<int>()) - .SelectList + .Select(list => list .Select(p => p.Name) - .SelectSubQuery(childCountQuery).WithAlias(() => childCountAlias) - .EndSelect - .OrderBy(() => childCountAlias).Desc + .SelectSubQuery(childCountQuery).WithAlias(() => childCountAlias)) + .OrderBy(() => childCountAlias).Desc .List<object[]>() .Select(props => new { Name = (string)props[0], Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2010-01-19 10:31:20 UTC (rev 4920) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/ProjectionsFixture.cs 2010-01-19 12:53:21 UTC (rev 4921) @@ -114,7 +114,7 @@ Person personAgeProjectionAlias = null; var actual = CreateTestQueryOver<Person>(() => personAlias) - .SelectList + .Select(list => list .SelectAvg(p => p.Age).WithAlias(() => personAgeProjectionAlias) .Select(Projections.Avg("Age")) // allows private properties .SelectAvg(() => personAlias.Age) @@ -132,8 +132,7 @@ .Select(() => personAlias.Age) .SelectSubQuery(DetachedQueryOverAge) .SelectSum(p => p.Age) - .SelectSum(() => personAlias.Age) - .EndSelect; + .SelectSum(() => personAlias.Age)); AssertCriteriaAreEqual(expected, actual); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-24 17:42:07
|
Revision: 4924 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4924&view=rev Author: ayenderahien Date: 2010-01-24 17:41:59 +0000 (Sun, 24 Jan 2010) Log Message: ----------- Adding error in the log about not using auto prop Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-24 16:46:51 UTC (rev 4923) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-24 17:41:59 UTC (rev 4924) @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.CompilerServices; using Iesi.Collections.Generic; using log4net; using NHibernate.Engine; @@ -229,6 +230,18 @@ else { log.Info("lazy property fetching available for: " + name); + foreach (var prop in persistentClass.PropertyClosureIterator) + { + if (prop.IsLazy == false) + continue; + + var getter = prop.GetGetter(persistentClass.MappedClass); + if(getter.Method == null || + getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false) + { + log.ErrorFormat("Lazy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name); + } + } } } Modified: trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs 2010-01-24 16:46:51 UTC (rev 4923) +++ trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs 2010-01-24 17:41:59 UTC (rev 4924) @@ -1,6 +1,8 @@ using System.Collections; +using log4net.Core; using NHibernate.ByteCode.Castle; using NHibernate.Cfg; +using NHibernate.Tuple.Entity; using NUnit.Framework; namespace NHibernate.Test.LazyProperty @@ -8,6 +10,8 @@ [TestFixture] public class LazyPropertyFixture : TestCase { + private string log; + protected override string MappingsAssembly { get { return "NHibernate.Test"; } @@ -24,6 +28,15 @@ typeof(ProxyFactoryFactory).AssemblyQualifiedName); } + protected override void BuildSessionFactory() + { + using (var logSpy = new LogSpy(typeof(EntityMetamodel))) + { + base.BuildSessionFactory(); + log = logSpy.GetWholeLog(); + } + } + protected override void OnSetUp() { using (var s = OpenSession()) @@ -70,6 +83,12 @@ } [Test] + public void ShouldGenerateErrorForNonAutoPropLazyProp() + { + Assert.IsTrue(log.Contains("Lazy property NHibernate.Test.LazyProperty.Book.ALotOfText is not an auto property, which may result in uninitialized property access")); + } + + [Test] public void PropertyLoadedNotInitializedWhenUsingGet() { using (ISession s = OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-24 21:46:57
|
Revision: 4925 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4925&view=rev Author: ayenderahien Date: 2010-01-24 21:46:35 +0000 (Sun, 24 Jan 2010) Log Message: ----------- adding support for ghost properties Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs trunk/nhibernate/src/NHibernate/Intercept/IFieldInterceptor.cs trunk/nhibernate/src/NHibernate/Mapping/Property.cs trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd trunk/nhibernate/src/NHibernate.ByteCode.Castle/LazyFieldInterceptor.cs trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/GhostProperty/ trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -672,11 +672,19 @@ /// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute("not-null")] public bool notnull; - + /// <remarks/> [System.Xml.Serialization.XmlIgnoreAttribute()] public bool notnullSpecified; - + + /// <remarks/> + [System.Xml.Serialization.XmlAttributeAttribute("force-load-on-property-access")] + public bool forceloadonpropertyaccess; + + /// <remarks/> + [System.Xml.Serialization.XmlAttributeAttribute()] + public bool forceloadonpropertyaccessSpecified; + /// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] [System.ComponentModel.DefaultValueAttribute(false)] Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -28,6 +28,11 @@ get { return optimisticlock; } } + public bool ForceLoadOnPropertyAccess + { + get { return forceloadonpropertyaccess; } + } + #endregion #region Overrides of AbstractDecoratable Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -107,6 +107,7 @@ var value = new ManyToOne(table); BindManyToOne(manyToOneMapping, value, propertyName, true); property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas); + property.IsGhostProperty = manyToOneMapping.ForceLoadOnPropertyAccess; BindManyToOneProperty(manyToOneMapping, property); } else if ((componentMapping = entityPropertyMapping as HbmComponent) != null) Modified: trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Event/Default/AbstractSaveEventListener.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -292,7 +292,7 @@ { if (FieldInterceptionHelper.IsInstrumented(entity)) { - IFieldInterceptor interceptor = FieldInterceptionHelper.InjectFieldInterceptor(entity, persister.EntityName, null, source); + IFieldInterceptor interceptor = FieldInterceptionHelper.InjectFieldInterceptor(entity, persister.EntityName, null, null, source); interceptor.MarkDirty(); } } Modified: trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -1,6 +1,7 @@ using System; using Iesi.Collections.Generic; using NHibernate.Engine; +using NHibernate.Proxy; namespace NHibernate.Intercept { @@ -12,16 +13,18 @@ [NonSerialized] private ISessionImplementor session; private ISet<string> uninitializedFields; + private ISet<string> uninitializedGhostFieldNames; private readonly string entityName; [NonSerialized] private bool initializing; private bool isDirty; - protected internal AbstractFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, string entityName) + protected internal AbstractFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, ISet<string> uninitializedGhostFieldNames, string entityName) { this.session = session; this.uninitializedFields = uninitializedFields; + this.uninitializedGhostFieldNames = uninitializedGhostFieldNames; this.entityName = entityName; } @@ -74,11 +77,9 @@ get { return initializing; } } - public object Intercept(object target, string fieldName) + public object Intercept(object target, string fieldName, object value) { - if (initializing || - uninitializedFields == null || - !uninitializedFields.Contains(fieldName)) + if (initializing) return InvokeImplementation; if (session == null) @@ -90,11 +91,38 @@ throw new LazyInitializationException("session is not connected"); } + if (uninitializedFields != null && uninitializedFields.Contains(fieldName)) + { + return InitializeField(fieldName, target); + } + if (value is INHibernateProxy && uninitializedGhostFieldNames != null && uninitializedGhostFieldNames.Contains(fieldName)) + { + return InitializeOrGetAssociation((INHibernateProxy)value); + } + return InvokeImplementation; + } + + private object InitializeOrGetAssociation(INHibernateProxy value) + { + if(value.HibernateLazyInitializer.IsUninitialized) + { + value.HibernateLazyInitializer.Initialize(); + var association = value.HibernateLazyInitializer.GetImplementation(session); + var narrowedProxy = session.PersistenceContext.ProxyFor(association); + // we set the narrowed impl here to be able to get it back in the future + value.HibernateLazyInitializer.SetImplementation(narrowedProxy); + } + return value.HibernateLazyInitializer.GetImplementation(session); + } + + private object InitializeField(string fieldName, object target) + { object result; initializing = true; try { - result = ((ILazyPropertyInitializer)session.Factory.GetEntityPersister(entityName)).InitializeLazyProperty(fieldName, target, session); + var lazyPropertyInitializer = ((ILazyPropertyInitializer) session.Factory.GetEntityPersister(entityName)); + result = lazyPropertyInitializer.InitializeLazyProperty(fieldName, target, session); } finally { Modified: trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -5,8 +5,8 @@ { public class DefaultFieldInterceptor : AbstractFieldInterceptor { - public DefaultFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, string entityName) - : base(session, uninitializedFields, entityName) + public DefaultFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, ISet<string> uninitializedGhostFieldNames, string entityName) + : base(session, uninitializedFields, uninitializedGhostFieldNames, entityName) { } } Modified: trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -32,12 +32,15 @@ return fieldInterceptorAccessor == null ? null : fieldInterceptorAccessor.FieldInterceptor; } - public static IFieldInterceptor InjectFieldInterceptor(object entity, string entityName, ISet<string> uninitializedFieldNames, ISessionImplementor session) + public static IFieldInterceptor InjectFieldInterceptor(object entity, string entityName, + ISet<string> uninitializedFieldNames, + ISet<string> uninitializedGhostFieldNames, + ISessionImplementor session) { var fieldInterceptorAccessor = entity as IFieldInterceptorAccessor; if (fieldInterceptorAccessor != null) { - var fieldInterceptorImpl = new DefaultFieldInterceptor(session, uninitializedFieldNames, entityName); + var fieldInterceptorImpl = new DefaultFieldInterceptor(session, uninitializedFieldNames, uninitializedGhostFieldNames, entityName); fieldInterceptorAccessor.FieldInterceptor = fieldInterceptorImpl; return fieldInterceptorImpl; } Modified: trunk/nhibernate/src/NHibernate/Intercept/IFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/IFieldInterceptor.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Intercept/IFieldInterceptor.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -28,6 +28,6 @@ void ClearDirty(); /// <summary> Intercept field set/get </summary> - object Intercept(object target, string fieldName); + object Intercept(object target, string fieldName, object value); } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Mapping/Property.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -132,10 +132,10 @@ { bool[] columnUpdateability = propertyValue.ColumnUpdateability; return updateable && - ( - // columnUpdateability.Length == 0 || - !ArrayHelper.IsAllFalse(columnUpdateability) - ); + ( + // columnUpdateability.Length == 0 || + !ArrayHelper.IsAllFalse(columnUpdateability) + ); } set { updateable = value; } } @@ -146,10 +146,10 @@ { bool[] columnInsertability = propertyValue.ColumnInsertability; return insertable && - ( - columnInsertability.Length == 0 || - !ArrayHelper.IsAllFalse(columnInsertability) - ); + ( + columnInsertability.Length == 0 || + !ArrayHelper.IsAllFalse(columnInsertability) + ); } set { insertable = value; } } @@ -206,7 +206,7 @@ public MetaAttribute GetMetaAttribute(string attributeName) { - if(metaAttributes == null) + if (metaAttributes == null) { return null; } @@ -226,7 +226,7 @@ { if (propertyValue is SimpleValue) { - return ((SimpleValue) propertyValue).NullValue; + return ((SimpleValue)propertyValue).NullValue; } else return null; @@ -304,5 +304,7 @@ get { return nodeName; } set { nodeName = value; } } + + public bool IsGhostProperty { get; set; } } } Modified: trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Persister/Entity/AbstractEntityPersister.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -3615,7 +3615,7 @@ } else { - IFieldInterceptor fieldInterceptor = FieldInterceptionHelper.InjectFieldInterceptor(entity, EntityName, null, session); + IFieldInterceptor fieldInterceptor = FieldInterceptionHelper.InjectFieldInterceptor(entity, EntityName, null, null, session); fieldInterceptor.MarkDirty(); } } Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -153,6 +153,11 @@ { hasLazy = true; } + if (prop.IsGhostProperty) + { + hasGhostProperties = true; + } + propertyLaziness[i] = lazyProperty; propertyNames[i] = properties[i].Name; @@ -230,20 +235,23 @@ else { log.Info("lazy property fetching available for: " + name); - foreach (var prop in persistentClass.PropertyClosureIterator) - { - if (prop.IsLazy == false) - continue; - - var getter = prop.GetGetter(persistentClass.MappedClass); - if(getter.Method == null || - getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false) - { - log.ErrorFormat("Lazy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name); - } - } + VerifyCanInterceptPropertiesForLazyOrGhostProperties(persistentClass); } } + if(hasGhostProperties) + { + if (lazy == false) + { + log.WarnFormat("Disabled ghost properies fetching for {0} beacuse it does not support lazy at the entity level", name); + hasGhostProperties = false; + } + else + { + log.Info("Ghost property fetching available for: " + name); + if (hasLazy == false) // avoid double checking + VerifyCanInterceptPropertiesForLazyOrGhostProperties(persistentClass); + } + } mutable = persistentClass.IsMutable; @@ -291,6 +299,22 @@ tuplizerMapping = new EntityEntityModeToTuplizerMapping(persistentClass, this); } + private static void VerifyCanInterceptPropertiesForLazyOrGhostProperties(PersistentClass persistentClass) + { + foreach (var prop in persistentClass.PropertyClosureIterator) + { + if (prop.IsLazy == false && prop.IsGhostProperty) + continue; + + var getter = prop.GetGetter(persistentClass.MappedClass); + if(getter.Method == null || + getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false) + { + log.ErrorFormat("Lazy or ghost property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name); + } + } + } + private ValueInclusion DetermineInsertValueGenerationType(Mapping.Property mappingProperty, StandardProperty runtimeProperty) { if (runtimeProperty.IsInsertGenerated) @@ -659,6 +683,7 @@ #region Tuplizer private readonly EntityEntityModeToTuplizerMapping tuplizerMapping; + private bool hasGhostProperties; public IEntityTuplizer GetTuplizer(EntityMode entityMode) { @@ -681,6 +706,11 @@ get { return naturalIdPropertyNumbers != null; } } + public bool HasGhostProperties + { + get { return hasGhostProperties; } + } + public bool HasNonIdentifierPropertyNamedId { get { return hasNonIdentifierPropertyNamedId; } Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -25,6 +25,7 @@ private readonly bool islifecycleImplementor; private readonly bool isValidatableImplementor; private readonly HashedSet<string> lazyPropertyNames = new HashedSet<string>(); + private readonly HashedSet<string> ghostPropertyNames = new HashedSet<string>(); [NonSerialized] private IReflectionOptimizer optimizer; private readonly IProxyValidator proxyValidator; @@ -54,6 +55,8 @@ { if (property.IsLazy) lazyPropertyNames.Add(property.Name); + if (property.IsGhostProperty) + ghostPropertyNames.Add(property.Name); } SetReflectionOptimizer(); @@ -74,10 +77,10 @@ public override bool IsInstrumented { - get { - return - EntityMetamodel.HasLazyProperties && - FieldInterceptionHelper.IsInstrumented(MappedClass); + get + { + return (EntityMetamodel.HasLazyProperties || EntityMetamodel.HasGhostProperties) + && FieldInterceptionHelper.IsInstrumented(MappedClass); } } @@ -101,12 +104,12 @@ if (optimizer == null) { log.Debug("Create Instantiator without optimizer for:" + persistentClass.MappedClass.FullName); - return new PocoInstantiator(persistentClass, null, ProxyFactory, EntityMetamodel.HasLazyProperties); + return new PocoInstantiator(persistentClass, null, ProxyFactory, EntityMetamodel.HasLazyProperties || EntityMetamodel.HasGhostProperties); } else { log.Debug("Create Instantiator using optimizer for:" + persistentClass.MappedClass.FullName); - return new PocoInstantiator(persistentClass, optimizer.InstantiationOptimizer, ProxyFactory, EntityMetamodel.HasLazyProperties); + return new PocoInstantiator(persistentClass, optimizer.InstantiationOptimizer, ProxyFactory, EntityMetamodel.HasLazyProperties || EntityMetamodel.HasGhostProperties); } } @@ -226,7 +229,7 @@ HashedSet<string> lazyProps = lazyPropertiesAreUnfetched && EntityMetamodel.HasLazyProperties ? lazyPropertyNames : null; //TODO: if we support multiple fetch groups, we would need // to clone the set of lazy properties! - FieldInterceptionHelper.InjectFieldInterceptor(entity, EntityName, lazyProps, session); + FieldInterceptionHelper.InjectFieldInterceptor(entity, EntityName, lazyProps, ghostPropertyNames, session); } } Modified: trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd =================================================================== --- trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd 2010-01-24 21:46:35 UTC (rev 4925) @@ -879,6 +879,8 @@ </xs:attribute> <xs:attribute name="unique" default="false" type="xs:boolean"> </xs:attribute> + <xs:attribute name="force-load-on-property-access" default="false" type="xs:boolean"> + </xs:attribute> <xs:attribute name="unique-key" type="xs:string" /> <xs:attribute name="index" type="xs:string" /> <xs:attribute name="cascade" type="xs:string" /> Modified: trunk/nhibernate/src/NHibernate.ByteCode.Castle/LazyFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate.ByteCode.Castle/LazyFieldInterceptor.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate.ByteCode.Castle/LazyFieldInterceptor.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -18,20 +18,22 @@ { if (ReflectHelper.IsPropertyGet(invocation.Method)) { - var result = FieldInterceptor.Intercept(invocation.InvocationTarget, ReflectHelper.GetPropertyName(invocation.Method)); - if (result == AbstractFieldInterceptor.InvokeImplementation) + invocation.Proceed(); // get the existing value + + var result = FieldInterceptor.Intercept( + invocation.InvocationTarget, + ReflectHelper.GetPropertyName(invocation.Method), + invocation.ReturnValue); + + if (result != AbstractFieldInterceptor.InvokeImplementation) { - invocation.Proceed(); - } - else - { invocation.ReturnValue = result; } } else if (ReflectHelper.IsPropertySet(invocation.Method)) { FieldInterceptor.MarkDirty(); - FieldInterceptor.Intercept(invocation.InvocationTarget, ReflectHelper.GetPropertyName(invocation.Method)); + FieldInterceptor.Intercept(invocation.InvocationTarget, ReflectHelper.GetPropertyName(invocation.Method), null); invocation.Proceed(); } } Property changes on: trunk/nhibernate/src/NHibernate.Test/GhostProperty ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -0,0 +1,81 @@ +using System.Collections; +using NHibernate.ByteCode.Castle; +using NHibernate.Cfg; +using NUnit.Framework; + +namespace NHibernate.Test.GhostProperty +{ + [TestFixture] + public class GhostPropertyFixture : TestCase + { + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + protected override IList Mappings + { + get { return new[] { "GhostProperty.Mappings.hbm.xml" }; } + } + + protected override void Configure(NHibernate.Cfg.Configuration configuration) + { + configuration.SetProperty(Environment.ProxyFactoryFactoryClass, + typeof(ProxyFactoryFactory).AssemblyQualifiedName); + } + + protected override void OnSetUp() + { + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + var wireTransfer = new WireTransfer + { + Id = 1 + }; + s.Persist(wireTransfer); + s.Persist(new Order + { + Id = 1, + Payment = wireTransfer + }); + tx.Commit(); + } + + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + s.Delete("from Order"); + s.Delete("from Payment"); + tx.Commit(); + } + } + + [Test] + public void CanGetActualValueFromLazyManyToOne() + { + using (ISession s = OpenSession()) + { + var order = s.Get<Order>(1); + + Assert.IsTrue(order.Payment is WireTransfer); + } + } + + [Test] + public void GhostPropertyMaintainIdentityMap() + { + using (ISession s = OpenSession()) + { + var order = s.Get<Order>(1); + + Assert.AreSame(order.Payment, s.Load<Payment>(1)); + } + } + + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml 2010-01-24 21:46:35 UTC (rev 4925) @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.GhostProperty"> + + <class name="Order" table="Orders"> + <id name="Id"> + <generator class="assigned" /> + </id> + <many-to-one name="Payment" force-load-on-property-access="true"/> + </class> + + + <class name="Payment" abstract="true"> + <id name="Id"> + <generator class="assigned" /> + </id> + <discriminator column="Type" type="System.String"/> + <subclass name="WireTransfer" discriminator-value="WT"> + + </subclass> + <subclass name="CreditCard" discriminator-value="CC"> + + </subclass> + + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -0,0 +1,16 @@ +namespace NHibernate.Test.GhostProperty +{ + public class Order + { + public virtual int Id { get; set; } + public virtual Payment Payment { get; set; } + } + + public abstract class Payment + { + public virtual int Id { get; set; } + } + + public class WireTransfer : Payment{} + public class CreditCard : Payment { } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate.Test/LazyProperty/LazyPropertyFixture.cs 2010-01-24 21:46:35 UTC (rev 4925) @@ -85,7 +85,7 @@ [Test] public void ShouldGenerateErrorForNonAutoPropLazyProp() { - Assert.IsTrue(log.Contains("Lazy property NHibernate.Test.LazyProperty.Book.ALotOfText is not an auto property, which may result in uninitialized property access")); + Assert.IsTrue(log.Contains("Lazy or ghost property NHibernate.Test.LazyProperty.Book.ALotOfText is not an auto property, which may result in uninitialized property access")); } [Test] Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-24 17:41:59 UTC (rev 4924) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-24 21:46:35 UTC (rev 4925) @@ -341,6 +341,8 @@ <Compile Include="GenericTest\SetGeneric\A.cs" /> <Compile Include="GenericTest\SetGeneric\B.cs" /> <Compile Include="GenericTest\SetGeneric\SetGenericFixture.cs" /> + <Compile Include="GhostProperty\Order.cs" /> + <Compile Include="GhostProperty\GhostPropertyFixture.cs" /> <Compile Include="HQL\Animal.cs" /> <Compile Include="HQL\Ast\Address.cs" /> <Compile Include="HQL\Ast\Animal.cs" /> @@ -2113,6 +2115,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="GhostProperty\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2065\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2009\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1989\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-24 22:44:52
|
Revision: 4926 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4926&view=rev Author: ayenderahien Date: 2010-01-24 22:44:45 +0000 (Sun, 24 Jan 2010) Log Message: ----------- modify ghost property functionality to use lazy='no-proxy' Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/Hbm.generated.cs 2010-01-24 22:44:45 UTC (rev 4926) @@ -678,14 +678,6 @@ public bool notnullSpecified; /// <remarks/> - [System.Xml.Serialization.XmlAttributeAttribute("force-load-on-property-access")] - public bool forceloadonpropertyaccess; - - /// <remarks/> - [System.Xml.Serialization.XmlAttributeAttribute()] - public bool forceloadonpropertyaccessSpecified; - - /// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] [System.ComponentModel.DefaultValueAttribute(false)] public bool unique; Modified: trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate/Cfg/MappingSchema/HbmManyToOne.cs 2010-01-24 22:44:45 UTC (rev 4926) @@ -28,11 +28,6 @@ get { return optimisticlock; } } - public bool ForceLoadOnPropertyAccess - { - get { return forceloadonpropertyaccess; } - } - #endregion #region Overrides of AbstractDecoratable Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs 2010-01-24 22:44:45 UTC (rev 4926) @@ -107,7 +107,7 @@ var value = new ManyToOne(table); BindManyToOne(manyToOneMapping, value, propertyName, true); property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas); - property.IsGhostProperty = manyToOneMapping.ForceLoadOnPropertyAccess; + property.IsGhostProperty = manyToOneMapping.Lazy == HbmLaziness.NoProxy; BindManyToOneProperty(manyToOneMapping, property); } else if ((componentMapping = entityPropertyMapping as HbmComponent) != null) Modified: trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate/Engine/StatefulPersistenceContext.cs 2010-01-24 22:44:45 UTC (rev 4926) @@ -720,6 +720,14 @@ } } + public void ClearProxyFor(IEntityPersister persister, EntityKey key) + { + if (!persister.HasProxy || key == null) + return; + + proxiesByKey.Remove(key); + } + /// <summary> /// Return the existing proxy associated with the given <tt>EntityKey</tt>, or the /// third argument (the entity associated with the key) if no proxy exists. Init Modified: trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-24 22:44:45 UTC (rev 4926) @@ -108,9 +108,14 @@ { value.HibernateLazyInitializer.Initialize(); var association = value.HibernateLazyInitializer.GetImplementation(session); - var narrowedProxy = session.PersistenceContext.ProxyFor(association); + //var narrowedProxy = session.PersistenceContext.ProxyFor(association); // we set the narrowed impl here to be able to get it back in the future - value.HibernateLazyInitializer.SetImplementation(narrowedProxy); + value.HibernateLazyInitializer.SetImplementation(association); + var entityPersister = session.GetEntityPersister(value.HibernateLazyInitializer.EntityName, value); + var key = new EntityKey(value.HibernateLazyInitializer.Identifier, + entityPersister, + session.EntityMode); + session.PersistenceContext.RemoveProxy(key); } return value.HibernateLazyInitializer.GetImplementation(session); } Modified: trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd =================================================================== --- trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate/nhibernate-mapping.xsd 2010-01-24 22:44:45 UTC (rev 4926) @@ -879,8 +879,6 @@ </xs:attribute> <xs:attribute name="unique" default="false" type="xs:boolean"> </xs:attribute> - <xs:attribute name="force-load-on-property-access" default="false" type="xs:boolean"> - </xs:attribute> <xs:attribute name="unique-key" type="xs:string" /> <xs:attribute name="index" type="xs:string" /> <xs:attribute name="cascade" type="xs:string" /> Modified: trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml 2010-01-24 21:46:35 UTC (rev 4925) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/Mappings.hbm.xml 2010-01-24 22:44:45 UTC (rev 4926) @@ -7,7 +7,7 @@ <id name="Id"> <generator class="assigned" /> </id> - <many-to-one name="Payment" force-load-on-property-access="true"/> + <many-to-one name="Payment" lazy="no-proxy"/> </class> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-25 07:33:07
|
Revision: 4927 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4927&view=rev Author: ayenderahien Date: 2010-01-25 07:33:00 +0000 (Mon, 25 Jan 2010) Log Message: ----------- Changing ghost property terminology from ghost to unwrap proxy (more accurate) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs trunk/nhibernate/src/NHibernate/Mapping/Property.cs trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs trunk/nhibernate/src/NHibernate/Tuple/PocoInstantiator.cs trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs Modified: trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Cfg/XmlHbmBinding/PropertiesBinder.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -107,7 +107,7 @@ var value = new ManyToOne(table); BindManyToOne(manyToOneMapping, value, propertyName, true); property = CreateProperty(entityPropertyMapping, className, value, inheritedMetas); - property.IsGhostProperty = manyToOneMapping.Lazy == HbmLaziness.NoProxy; + property.UnwrapProxy = manyToOneMapping.Lazy == HbmLaziness.NoProxy; BindManyToOneProperty(manyToOneMapping, property); } else if ((componentMapping = entityPropertyMapping as HbmComponent) != null) Modified: trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -13,18 +13,18 @@ [NonSerialized] private ISessionImplementor session; private ISet<string> uninitializedFields; - private ISet<string> uninitializedGhostFieldNames; + private ISet<string> unwrapProxyFieldNames; private readonly string entityName; [NonSerialized] private bool initializing; private bool isDirty; - protected internal AbstractFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, ISet<string> uninitializedGhostFieldNames, string entityName) + protected internal AbstractFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, ISet<string> unwrapProxyFieldNames, string entityName) { this.session = session; this.uninitializedFields = uninitializedFields; - this.uninitializedGhostFieldNames = uninitializedGhostFieldNames; + this.unwrapProxyFieldNames = unwrapProxyFieldNames; this.entityName = entityName; } @@ -95,7 +95,7 @@ { return InitializeField(fieldName, target); } - if (value is INHibernateProxy && uninitializedGhostFieldNames != null && uninitializedGhostFieldNames.Contains(fieldName)) + if (value is INHibernateProxy && unwrapProxyFieldNames != null && unwrapProxyFieldNames.Contains(fieldName)) { return InitializeOrGetAssociation((INHibernateProxy)value); } Modified: trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Intercept/DefaultFieldInterceptor.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -5,8 +5,8 @@ { public class DefaultFieldInterceptor : AbstractFieldInterceptor { - public DefaultFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, ISet<string> uninitializedGhostFieldNames, string entityName) - : base(session, uninitializedFields, uninitializedGhostFieldNames, entityName) + public DefaultFieldInterceptor(ISessionImplementor session, ISet<string> uninitializedFields, ISet<string> unwrapProxyFieldNames, string entityName) + : base(session, uninitializedFields, unwrapProxyFieldNames, entityName) { } } Modified: trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Intercept/FieldInterceptionHelper.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -34,13 +34,13 @@ public static IFieldInterceptor InjectFieldInterceptor(object entity, string entityName, ISet<string> uninitializedFieldNames, - ISet<string> uninitializedGhostFieldNames, + ISet<string> unwrapProxyFieldNames, ISessionImplementor session) { var fieldInterceptorAccessor = entity as IFieldInterceptorAccessor; if (fieldInterceptorAccessor != null) { - var fieldInterceptorImpl = new DefaultFieldInterceptor(session, uninitializedFieldNames, uninitializedGhostFieldNames, entityName); + var fieldInterceptorImpl = new DefaultFieldInterceptor(session, uninitializedFieldNames, unwrapProxyFieldNames, entityName); fieldInterceptorAccessor.FieldInterceptor = fieldInterceptorImpl; return fieldInterceptorImpl; } Modified: trunk/nhibernate/src/NHibernate/Mapping/Property.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -305,6 +305,6 @@ set { nodeName = value; } } - public bool IsGhostProperty { get; set; } + public bool UnwrapProxy { get; set; } } } Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -153,9 +153,9 @@ { hasLazy = true; } - if (prop.IsGhostProperty) + if (prop.UnwrapProxy) { - hasGhostProperties = true; + hasUnwrapProxyForProperties = true; } propertyLaziness[i] = lazyProperty; @@ -238,12 +238,12 @@ VerifyCanInterceptPropertiesForLazyOrGhostProperties(persistentClass); } } - if(hasGhostProperties) + if(hasUnwrapProxyForProperties) { if (lazy == false) { log.WarnFormat("Disabled ghost properies fetching for {0} beacuse it does not support lazy at the entity level", name); - hasGhostProperties = false; + hasUnwrapProxyForProperties = false; } else { @@ -303,7 +303,7 @@ { foreach (var prop in persistentClass.PropertyClosureIterator) { - if (prop.IsLazy == false && prop.IsGhostProperty) + if (prop.IsLazy == false && prop.UnwrapProxy) continue; var getter = prop.GetGetter(persistentClass.MappedClass); @@ -683,7 +683,7 @@ #region Tuplizer private readonly EntityEntityModeToTuplizerMapping tuplizerMapping; - private bool hasGhostProperties; + private bool hasUnwrapProxyForProperties; public IEntityTuplizer GetTuplizer(EntityMode entityMode) { @@ -706,9 +706,9 @@ get { return naturalIdPropertyNumbers != null; } } - public bool HasGhostProperties + public bool HasUnwrapProxyForProperties { - get { return hasGhostProperties; } + get { return hasUnwrapProxyForProperties;c } } public bool HasNonIdentifierPropertyNamedId Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/PocoEntityTuplizer.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -25,7 +25,7 @@ private readonly bool islifecycleImplementor; private readonly bool isValidatableImplementor; private readonly HashedSet<string> lazyPropertyNames = new HashedSet<string>(); - private readonly HashedSet<string> ghostPropertyNames = new HashedSet<string>(); + private readonly HashedSet<string> unwrapProxyPropertyNames = new HashedSet<string>(); [NonSerialized] private IReflectionOptimizer optimizer; private readonly IProxyValidator proxyValidator; @@ -55,8 +55,8 @@ { if (property.IsLazy) lazyPropertyNames.Add(property.Name); - if (property.IsGhostProperty) - ghostPropertyNames.Add(property.Name); + if (property.UnwrapProxy) + unwrapProxyPropertyNames.Add(property.Name); } SetReflectionOptimizer(); @@ -79,7 +79,7 @@ { get { - return (EntityMetamodel.HasLazyProperties || EntityMetamodel.HasGhostProperties) + return (EntityMetamodel.HasLazyProperties || EntityMetamodel.HasUnwrapProxyForProperties) && FieldInterceptionHelper.IsInstrumented(MappedClass); } } @@ -104,12 +104,12 @@ if (optimizer == null) { log.Debug("Create Instantiator without optimizer for:" + persistentClass.MappedClass.FullName); - return new PocoInstantiator(persistentClass, null, ProxyFactory, EntityMetamodel.HasLazyProperties || EntityMetamodel.HasGhostProperties); + return new PocoInstantiator(persistentClass, null, ProxyFactory, EntityMetamodel.HasLazyProperties || EntityMetamodel.HasUnwrapProxyForProperties); } else { log.Debug("Create Instantiator using optimizer for:" + persistentClass.MappedClass.FullName); - return new PocoInstantiator(persistentClass, optimizer.InstantiationOptimizer, ProxyFactory, EntityMetamodel.HasLazyProperties || EntityMetamodel.HasGhostProperties); + return new PocoInstantiator(persistentClass, optimizer.InstantiationOptimizer, ProxyFactory, EntityMetamodel.HasLazyProperties || EntityMetamodel.HasUnwrapProxyForProperties); } } @@ -229,7 +229,7 @@ HashedSet<string> lazyProps = lazyPropertiesAreUnfetched && EntityMetamodel.HasLazyProperties ? lazyPropertyNames : null; //TODO: if we support multiple fetch groups, we would need // to clone the set of lazy properties! - FieldInterceptionHelper.InjectFieldInterceptor(entity, EntityName, lazyProps, ghostPropertyNames, session); + FieldInterceptionHelper.InjectFieldInterceptor(entity, EntityName, lazyProps, unwrapProxyPropertyNames, session); } } Modified: trunk/nhibernate/src/NHibernate/Tuple/PocoInstantiator.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/PocoInstantiator.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate/Tuple/PocoInstantiator.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -22,7 +22,7 @@ private readonly IProxyFactory proxyFactory; - private readonly bool hasLazyProperties; + private readonly bool generateFieldInterceptionProxy; private readonly bool embeddedIdentifier; @@ -54,14 +54,14 @@ } } - public PocoInstantiator(PersistentClass persistentClass, IInstantiationOptimizer optimizer, IProxyFactory proxyFactory, bool hasLazyProperties) + public PocoInstantiator(PersistentClass persistentClass, IInstantiationOptimizer optimizer, IProxyFactory proxyFactory, bool generateFieldInterceptionProxy) { mappedClass = persistentClass.MappedClass; proxyInterface = persistentClass.ProxyInterface; embeddedIdentifier = persistentClass.HasEmbeddedIdentifier; this.optimizer = optimizer; this.proxyFactory = proxyFactory; - this.hasLazyProperties = hasLazyProperties; + this.generateFieldInterceptionProxy = generateFieldInterceptionProxy; try { @@ -88,7 +88,7 @@ { throw new InstantiationException("Cannot instantiate abstract class or interface: ", mappedClass); } - if (hasLazyProperties) + if (generateFieldInterceptionProxy) { return proxyFactory.GetFieldInterceptionProxy(); } Modified: trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-24 22:44:45 UTC (rev 4926) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-25 07:33:00 UTC (rev 4927) @@ -77,5 +77,18 @@ } } + [Test] + public void GhostPropertyMaintainIdentityMapUsingGet() + { + using (ISession s = OpenSession()) + { + var payment = s.Load<Payment>(1); + var order = s.Get<Order>(1); + + Assert.AreSame(order.Payment, payment); + } + } + + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-26 09:25:33
|
Revision: 4931 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4931&view=rev Author: ayenderahien Date: 2010-01-26 09:25:25 +0000 (Tue, 26 Jan 2010) Log Message: ----------- Simplifying no-proxy implementation, adding comments to point out differences from hibernate Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs trunk/nhibernate/src/NHibernate/Mapping/Property.cs trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs Modified: trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-25 21:57:55 UTC (rev 4930) +++ trunk/nhibernate/src/NHibernate/Intercept/AbstractFieldInterceptor.cs 2010-01-26 09:25:25 UTC (rev 4931) @@ -13,7 +13,8 @@ [NonSerialized] private ISessionImplementor session; private ISet<string> uninitializedFields; - private ISet<string> unwrapProxyFieldNames; + private readonly ISet<string> unwrapProxyFieldNames; + private readonly ISet<string> loadedUnwrapProxyFieldNames = new HashedSet<string>(); private readonly string entityName; [NonSerialized] @@ -47,6 +48,10 @@ public bool IsInitializedField(string field) { + if (unwrapProxyFieldNames != null && unwrapProxyFieldNames.Contains(field)) + { + return loadedUnwrapProxyFieldNames.Contains(field); + } return uninitializedFields == null || !uninitializedFields.Contains(field); } @@ -77,6 +82,8 @@ get { return initializing; } } + // NH Specific: Hibernate only deals with lazy properties here, we deal with + // both lazy properties and with no-proxy. public object Intercept(object target, string fieldName, object value) { if (initializing) @@ -97,25 +104,18 @@ } if (value is INHibernateProxy && unwrapProxyFieldNames != null && unwrapProxyFieldNames.Contains(fieldName)) { - return InitializeOrGetAssociation((INHibernateProxy)value); + return InitializeOrGetAssociation((INHibernateProxy)value, fieldName); } return InvokeImplementation; } - private object InitializeOrGetAssociation(INHibernateProxy value) + private object InitializeOrGetAssociation(INHibernateProxy value, string fieldName) { if(value.HibernateLazyInitializer.IsUninitialized) { value.HibernateLazyInitializer.Initialize(); - var association = value.HibernateLazyInitializer.GetImplementation(session); - //var narrowedProxy = session.PersistenceContext.ProxyFor(association); - // we set the narrowed impl here to be able to get it back in the future - value.HibernateLazyInitializer.SetImplementation(association); - var entityPersister = session.GetEntityPersister(value.HibernateLazyInitializer.EntityName, value); - var key = new EntityKey(value.HibernateLazyInitializer.Identifier, - entityPersister, - session.EntityMode); - session.PersistenceContext.RemoveProxy(key); + value.HibernateLazyInitializer.Unwrap = true; // means that future Load/Get from the session will get the implementation + loadedUnwrapProxyFieldNames.Add(fieldName); } return value.HibernateLazyInitializer.GetImplementation(session); } Modified: trunk/nhibernate/src/NHibernate/Mapping/Property.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2010-01-25 21:57:55 UTC (rev 4930) +++ trunk/nhibernate/src/NHibernate/Mapping/Property.cs 2010-01-26 09:25:25 UTC (rev 4931) @@ -261,28 +261,10 @@ { get { - if (propertyValue is ToOne) - { - // both many-to-one and one-to-one are represented as a - // Property. EntityPersister is relying on this value to - // determine "lazy fetch groups" in terms of field-level - // interception. So we need to make sure that we return - // true here for the case of many-to-one and one-to-one - // with lazy="no-proxy" - // - // * impl note - lazy="no-proxy" currently forces both - // lazy and unwrap to be set to true. The other case we - // are extremely interested in here is that of lazy="proxy" - // where lazy is set to true, but unwrap is set to false. - // thus we use both here under the assumption that this - // return is really only ever used during persister - // construction to determine the lazy property/field fetch - // groupings. If that assertion changes then this check - // needs to change as well. Partially, this is an issue with - // the overloading of the term "lazy" here... - ToOne toOneValue = (ToOne)propertyValue; - return toOneValue.IsLazy && toOneValue.UnwrapProxy; - } + // NH Specific: Hibernate doesn't make a distinction between + // lazy and no-proxy, but NHibernate does. While Hibernate tracks + // just whatever a property is lazy, we need to track lazy/no-proxy seperatedly. + return isLazy; } set { isLazy = value; } @@ -305,6 +287,12 @@ set { nodeName = value; } } + // both many-to-one and one-to-one are represented as a + // Property. EntityPersister is relying on this value to + // determine "lazy fetch groups" in terms of field-level + // interception. So we need to make sure that we return + // true here for the case of many-to-one and one-to-one + // with lazy="no-proxy" public bool UnwrapProxy { get; set; } } } Modified: trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-25 21:57:55 UTC (rev 4930) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-26 09:25:25 UTC (rev 4931) @@ -67,6 +67,16 @@ } [Test] + public void WillNotLoadGhostPropertyByDefault() + { + using (ISession s = OpenSession()) + { + var order = s.Get<Order>(1); + Assert.IsFalse(NHibernateUtil.IsPropertyInitialized(order, "Payment")); + } + } + + [Test] public void GhostPropertyMaintainIdentityMap() { using (ISession s = OpenSession()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-01-26 23:28:26
|
Revision: 4932 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4932&view=rev Author: ricbrown Date: 2010-01-26 23:28:18 +0000 (Tue, 26 Jan 2010) Log Message: ----------- Fix NH-2020 (ISQLExceptionConverter does not get called if batch size enabled) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/AdoNet/SqlClientSqlCommandSet.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Model.cs Modified: trunk/nhibernate/src/NHibernate/AdoNet/SqlClientSqlCommandSet.cs =================================================================== --- trunk/nhibernate/src/NHibernate/AdoNet/SqlClientSqlCommandSet.cs 2010-01-26 09:25:25 UTC (rev 4931) +++ trunk/nhibernate/src/NHibernate/AdoNet/SqlClientSqlCommandSet.cs 2010-01-26 23:28:18 UTC (rev 4932) @@ -111,16 +111,10 @@ if (Connection == null) throw new ArgumentNullException( "Connection was not set! You must set the connection property before calling ExecuteNonQuery()"); - try - { - if (CountOfCommands == 0) - return 0; - return doExecuteNonQuery(); - } - catch (Exception e) - { - throw new HibernateException("An exception occurred when executing batch queries", e); - } + + if (CountOfCommands == 0) + return 0; + return doExecuteNonQuery(); } public SqlConnection Connection Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Fixture.cs 2010-01-26 23:28:18 UTC (rev 4932) @@ -0,0 +1,75 @@ +using System; + +using NUnit.Framework; + +using NHibernate.Dialect; +using NHibernate.Exceptions; +using NHibernate.Test.ExceptionsTest; + +namespace NHibernate.Test.NHSpecificTest.NH2020 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void Configure(Cfg.Configuration configuration) + { + configuration.SetProperty(Cfg.Environment.BatchSize, "1"); + + configuration.SetProperty( Cfg.Environment.SqlExceptionConverter, + typeof (MSSQLExceptionConverterExample).AssemblyQualifiedName); + } + + protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect) + { + return dialect is MsSql2000Dialect; + } + + protected override void OnTearDown() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + s.Delete("from One"); + s.Delete("from Many"); + tx.Commit(); + } + } + + [Test] + public void ISQLExceptionConverter_gets_called_if_batch_size_enabled() + { + long oneId; + + using(var s = OpenSession()) + using(var tx = s.BeginTransaction()) + { + var one = new One(); + s.Save(one); + + var many = new Many { One = one }; + s.Save(many); + + tx.Commit(); + + oneId = one.Id; + } + + using(ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + var one = s.Load<One>(oneId); + + try + { + s.Delete(one); + tx.Commit(); + Assert.Fail("DELETE should have failed"); + } + catch (Exception ex) + { + Assert.IsInstanceOf<ConstraintViolationException>(ex); + } + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Mappings.hbm.xml 2010-01-26 23:28:18 UTC (rev 4932) @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2020"> + + <class name="One"> + <id name="Id"> + <generator class="native"/> + </id> + </class> + + <class name="Many"> + <id name="Id"> + <generator class="native"/> + </id> + <many-to-one name="One" /> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2020/Model.cs 2010-01-26 23:28:18 UTC (rev 4932) @@ -0,0 +1,13 @@ +namespace NHibernate.Test.NHSpecificTest.NH2020 +{ + public class One + { + public virtual long Id { get; set; } + } + + public class Many + { + public virtual long Id { get; set; } + public virtual One One { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-26 09:25:25 UTC (rev 4931) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-26 23:28:18 UTC (rev 4932) @@ -667,6 +667,8 @@ <Compile Include="NHSpecificTest\NH1989\Model.cs" /> <Compile Include="NHSpecificTest\NH2009\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2009\Model.cs" /> + <Compile Include="NHSpecificTest\NH2020\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2020\Model.cs" /> <Compile Include="NHSpecificTest\NH2044\DomainClass.cs" /> <Compile Include="NHSpecificTest\NH2044\SampleTest.cs" /> <Compile Include="NHSpecificTest\NH2055\AuxType.cs" /> @@ -2115,6 +2117,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2020\Mappings.hbm.xml" /> <EmbeddedResource Include="GhostProperty\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2065\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2009\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-27 13:53:51
|
Revision: 4933 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4933&view=rev Author: ayenderahien Date: 2010-01-27 13:53:45 +0000 (Wed, 27 Jan 2010) Log Message: ----------- Adding appropriate alert for non auto prop ghost property Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs Modified: trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-26 23:28:18 UTC (rev 4932) +++ trunk/nhibernate/src/NHibernate/Tuple/Entity/EntityMetamodel.cs 2010-01-27 13:53:45 UTC (rev 4933) @@ -303,7 +303,8 @@ { foreach (var prop in persistentClass.PropertyClosureIterator) { - if (prop.IsLazy == false && prop.UnwrapProxy) + if (prop.IsLazy == false && + prop.UnwrapProxy == false) continue; var getter = prop.GetGetter(persistentClass.MappedClass); Modified: trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-26 23:28:18 UTC (rev 4932) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/GhostPropertyFixture.cs 2010-01-27 13:53:45 UTC (rev 4933) @@ -1,6 +1,7 @@ using System.Collections; using NHibernate.ByteCode.Castle; using NHibernate.Cfg; +using NHibernate.Tuple.Entity; using NUnit.Framework; namespace NHibernate.Test.GhostProperty @@ -8,6 +9,8 @@ [TestFixture] public class GhostPropertyFixture : TestCase { + private string log; + protected override string MappingsAssembly { get { return "NHibernate.Test"; } @@ -55,7 +58,22 @@ } } + protected override void BuildSessionFactory() + { + using (var logSpy = new LogSpy(typeof(EntityMetamodel))) + { + base.BuildSessionFactory(); + log = logSpy.GetWholeLog(); + } + } + [Test] + public void ShouldGenerateErrorForNonAutoPropGhostProp() + { + Assert.IsTrue(log.Contains("Lazy or ghost property NHibernate.Test.GhostProperty.Order.Payment is not an auto property, which may result in uninitialized property access")); + } + + [Test] public void CanGetActualValueFromLazyManyToOne() { using (ISession s = OpenSession()) Modified: trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs 2010-01-26 23:28:18 UTC (rev 4932) +++ trunk/nhibernate/src/NHibernate.Test/GhostProperty/Order.cs 2010-01-27 13:53:45 UTC (rev 4933) @@ -3,7 +3,13 @@ public class Order { public virtual int Id { get; set; } - public virtual Payment Payment { get; set; } + private Payment payment; + + public virtual Payment Payment + { + get { return payment; } + set { payment = value; } + } } public abstract class Payment This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-27 14:00:21
|
Revision: 4934 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4934&view=rev Author: ayenderahien Date: 2010-01-27 14:00:14 +0000 (Wed, 27 Jan 2010) Log Message: ----------- Applying patch from Richard Birkb, fixing NH-2086 Fixing schema issue with SQL CE Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/MsSqlCeDialect.cs trunk/nhibernate/src/NHibernate.Test/DialectTest/SqlCEDialectFixture.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSqlCeDialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSqlCeDialect.cs 2010-01-27 13:53:45 UTC (rev 4933) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSqlCeDialect.cs 2010-01-27 14:00:14 UTC (rev 4934) @@ -1,7 +1,9 @@ using System.Data; using System.Data.Common; +using System.Text; using NHibernate.Dialect.Schema; -using Environment=NHibernate.Cfg.Environment; +using NHibernate.Util; +using Environment = NHibernate.Cfg.Environment; namespace NHibernate.Dialect { @@ -97,5 +99,51 @@ { return new MsSqlCeDataBaseSchema(connection); } - } + + public override string Qualify(string catalog, string schema, string table) + { + // SQL Server Compact doesn't support Schemas. So join schema name and table name with underscores + // similar to the SQLLite dialect. + + var qualifiedName = new StringBuilder(); + bool quoted = false; + + if (!string.IsNullOrEmpty(catalog)) + { + qualifiedName.Append(catalog).Append(StringHelper.Dot); + } + + var tableName = new StringBuilder(); + if (!string.IsNullOrEmpty(schema)) + { + if (schema.StartsWith(OpenQuote.ToString())) + { + schema = schema.Substring(1, schema.Length - 1); + quoted = true; + } + if (schema.EndsWith(CloseQuote.ToString())) + { + schema = schema.Substring(0, schema.Length - 1); + quoted = true; + } + tableName.Append(schema).Append(StringHelper.Underscore); + } + + if (table.StartsWith(OpenQuote.ToString())) + { + table = table.Substring(1, table.Length - 1); + quoted = true; + } + if (table.EndsWith(CloseQuote.ToString())) + { + table = table.Substring(0, table.Length - 1); + quoted = true; + } + + string name = tableName.Append(table).ToString(); + if (quoted) + name = OpenQuote + name + CloseQuote; + return qualifiedName.Append(name).ToString(); + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/DialectTest/SqlCEDialectFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/DialectTest/SqlCEDialectFixture.cs 2010-01-27 13:53:45 UTC (rev 4933) +++ trunk/nhibernate/src/NHibernate.Test/DialectTest/SqlCEDialectFixture.cs 2010-01-27 14:00:14 UTC (rev 4934) @@ -7,10 +7,17 @@ [TestFixture] public class SqlCEDialectFixture { - [Test] + private MsSqlCeDialect dialect; + + [SetUp] + public void SetUp() + { + dialect = new MsSqlCeDialect(); + } + + [Test] public void BinaryBlob_mapping_to_SqlCe_types() { - Dialect dialect = new MsSqlCeDialect(); SimpleValue sv = new SimpleValue(); sv.TypeName = NHibernateUtil.BinaryBlob.Name; Column column = new Column(); @@ -26,5 +33,68 @@ column.Length = 8001; Assert.AreEqual("IMAGE", column.GetSqlType(dialect, null)); } - } + + [Test] + public void QuotedSchemaNameWithSqlCE() + { + Table tbl = new Table(); + tbl.Schema = "`schema`"; + tbl.Name = "`name`"; + + Assert.AreEqual("\"schema_name\"", tbl.GetQualifiedName(dialect)); + Assert.AreEqual("\"schema_table\"", dialect.Qualify("", "\"schema\"", "\"table\"")); + } + + [Test] + public void QuotedTableNameWithoutSchemaWithSqlCE() + { + Table tbl = new Table(); + tbl.Name = "`name`"; + + Assert.AreEqual("\"name\"", tbl.GetQualifiedName(dialect)); + } + + [Test] + public void QuotedSchemaNameWithUnqoutedTableInSqlCE() + { + Table tbl = new Table(); + tbl.Schema = "`schema`"; + tbl.Name = "name"; + + Assert.AreEqual("\"schema_name\"", tbl.GetQualifiedName(dialect)); + Assert.AreEqual("\"schema_table\"", dialect.Qualify("", "\"schema\"", "table")); + } + + [Test] + public void QuotedCatalogSchemaNameWithSqlCE() + { + Table tbl = new Table(); + tbl.Catalog = "dbo"; + tbl.Schema = "`schema`"; + tbl.Name = "`name`"; + + Assert.AreEqual("dbo.\"schema_name\"", tbl.GetQualifiedName(dialect)); + Assert.AreEqual("dbo.\"schema_table\"", dialect.Qualify("dbo", "\"schema\"", "\"table\"")); + } + + [Test] + public void QuotedTableNameWithSqlCE() + { + Table tbl = new Table(); + tbl.Name = "`Group`"; + + Assert.AreEqual("\"Group\"", tbl.GetQualifiedName(dialect)); + } + + [Test] + public void SchemaNameWithSqlCE() + { + Table tbl = new Table(); + tbl.Schema = "schema"; + tbl.Name = "name"; + + Assert.AreEqual("schema_name", tbl.GetQualifiedName(dialect)); + Assert.AreEqual("schema_table", dialect.Qualify("", "schema", "table")); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-27 14:38:49
|
Revision: 4935 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4935&view=rev Author: ayenderahien Date: 2010-01-27 14:38:34 +0000 (Wed, 27 Jan 2010) Log Message: ----------- Fixing NH-2084 - multiple future queries using same parameter name. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2010-01-27 14:00:14 UTC (rev 4934) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2010-01-27 14:38:34 UTC (rev 4935) @@ -38,10 +38,8 @@ private readonly Dialect.Dialect dialect; private bool forceCacheRefresh; private QueryParameters combinedParameters; - private readonly List<string> namedParametersThatAreSafeToDuplicate = new List<string>(); private FlushMode flushMode = FlushMode.Unspecified; private FlushMode sessionFlushMode = FlushMode.Unspecified; - private static readonly Regex parseParameterListOrignialName = new Regex(@"(?<orgname>.*?)_\d+_", RegexOptions.Compiled); public MultiQueryImpl(ISessionImplementor session) { @@ -75,7 +73,6 @@ public IMultiQuery SetParameter(string name, object val, IType type) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetParameter(name, val, type); @@ -85,7 +82,6 @@ public IMultiQuery SetParameter(string name, object val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetParameter(name, val); @@ -95,7 +91,6 @@ public IMultiQuery SetParameterList(string name, ICollection vals, IType type) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetParameterList(name, vals, type); @@ -105,7 +100,6 @@ public IMultiQuery SetParameterList(string name, ICollection vals) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetParameterList(name, vals); @@ -115,7 +109,6 @@ public IMultiQuery SetAnsiString(string name, string val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetAnsiString(name, val); @@ -125,7 +118,6 @@ public IMultiQuery SetBinary(string name, byte[] val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetBinary(name, val); @@ -135,7 +127,6 @@ public IMultiQuery SetBoolean(string name, bool val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetBoolean(name, val); @@ -145,7 +136,6 @@ public IMultiQuery SetByte(string name, byte val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetByte(name, val); @@ -155,7 +145,6 @@ public IMultiQuery SetCharacter(string name, char val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetCharacter(name, val); @@ -165,7 +154,6 @@ public IMultiQuery SetDateTime(string name, DateTime val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetDateTime(name, val); @@ -175,7 +163,6 @@ public IMultiQuery SetDecimal(string name, decimal val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetDecimal(name, val); @@ -185,7 +172,6 @@ public IMultiQuery SetDouble(string name, double val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetDouble(name, val); @@ -195,7 +181,6 @@ public IMultiQuery SetEntity(string name, object val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetEntity(name, val); @@ -205,7 +190,6 @@ public IMultiQuery SetEnum(string name, Enum val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetEnum(name, val); @@ -215,7 +199,6 @@ public IMultiQuery SetInt16(string name, short val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetInt16(name, val); @@ -225,7 +208,6 @@ public IMultiQuery SetInt32(string name, int val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetInt32(name, val); @@ -235,7 +217,6 @@ public IMultiQuery SetInt64(string name, long val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetInt64(name, val); @@ -245,7 +226,6 @@ public IMultiQuery SetSingle(string name, float val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetSingle(name, val); @@ -255,7 +235,6 @@ public IMultiQuery SetString(string name, string val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetString(name, val); @@ -265,7 +244,6 @@ public IMultiQuery SetGuid(string name, Guid val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetGuid(name, val); @@ -275,7 +253,6 @@ public IMultiQuery SetTime(string name, DateTime val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetTime(name, val); @@ -285,7 +262,6 @@ public IMultiQuery SetTimestamp(string name, DateTime val) { - namedParametersThatAreSafeToDuplicate.Add(name); foreach (IQuery query in queries) { query.SetTimestamp(name, val); @@ -797,9 +773,14 @@ combinedQueryParameters.NamedParameters = new Dictionary<string, TypedValue>(); ArrayList positionalParameterTypes = new ArrayList(); ArrayList positionalParameterValues = new ArrayList(); + int index = 0; foreach (QueryParameters queryParameters in Parameters) { - CopyNamedParametersDictionary(combinedQueryParameters.NamedParameters, queryParameters.NamedParameters); + foreach (KeyValuePair<string, TypedValue> dictionaryEntry in queryParameters.NamedParameters) + { + combinedQueryParameters.NamedParameters.Add(dictionaryEntry.Key + index, dictionaryEntry.Value); + } + index += 1; positionalParameterTypes.AddRange(queryParameters.PositionalParameterTypes); positionalParameterValues.AddRange(queryParameters.PositionalParameterValues); } @@ -818,37 +799,6 @@ } } - private void CopyNamedParametersDictionary(IDictionary<string, TypedValue> dest, IDictionary<string, TypedValue> src) - { - foreach (KeyValuePair<string, TypedValue> dictionaryEntry in src) - { - if (dest.ContainsKey(dictionaryEntry.Key)) - { - if (IsParameterSafeToDuplicate(dictionaryEntry.Key)) - continue; //we specify it for all the queries, so it is okay. - - throw new QueryException( - string.Format( - "The named parameter {0} was used in more than one query. Either give unique names to your parameters, or use the multi query SetParameter() methods to set the named parameter", - dictionaryEntry.Key)); - } - dest.Add(dictionaryEntry.Key, dictionaryEntry.Value); - } - } - - private bool IsParameterSafeToDuplicate(string name) - { - if (namedParametersThatAreSafeToDuplicate.Contains(name)) - return true; - Match match = parseParameterListOrignialName.Match(name); - if (match != null) - { - string originalName = match.Groups["orgname"].Value; - return namedParametersThatAreSafeToDuplicate.Contains(originalName); - } - return false; - } - private void ThrowIfKeyAlreadyExists(string key) { if (criteriaResultPositions.ContainsKey(key)) Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs 2010-01-27 14:00:14 UTC (rev 4934) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/Futures/FutureQueryFixture.cs 2010-01-27 14:38:34 UTC (rev 4935) @@ -94,5 +94,37 @@ } } } + + [Test] + public void CanExecuteMultipleQueryWithSameParameterName() + { + using (var s = sessions.OpenSession()) + { + IgnoreThisTestIfMultipleQueriesArentSupportedByDriver(); + + var meContainer = s.CreateQuery("from Person p where p.Id = :personId") + .SetParameter("personId", 1) + .FutureValue<Person>(); + + var possiblefriends = s.CreateQuery("from Person p where p.Id != :personId") + .SetParameter("personId", 2) + .Future<Person>(); + + using (var logSpy = new SqlLogSpy()) + { + var me = meContainer.Value; + + foreach (var person in possiblefriends) + { + } + + var events = logSpy.Appender.GetEvents(); + Assert.AreEqual(1, events.Length); + var wholeLog = logSpy.GetWholeLog(); + Assert.True(wholeLog.Contains("@p0 = 1 [Type: Int32 (0)], @p1 = 2 [Type: Int32 (0)]")); + } + } + + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-27 15:08:35
|
Revision: 4937 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4937&view=rev Author: ayenderahien Date: 2010-01-27 15:07:21 +0000 (Wed, 27 Jan 2010) Log Message: ----------- Fixing NH-2077 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Classic/ParserHelper.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Model.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/ParserHelper.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Classic/ParserHelper.cs 2010-01-27 14:40:36 UTC (rev 4936) +++ trunk/nhibernate/src/NHibernate/Hql/Classic/ParserHelper.cs 2010-01-27 15:07:21 UTC (rev 4937) @@ -7,7 +7,7 @@ { public const string HqlVariablePrefix = ":"; - public const string HqlSeparators = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\"; + public const string HqlSeparators = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\;"; //NOTICE: no " or . since they are part of (compound) identifiers public const string PathSeparators = "."; Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Fixture.cs 2010-01-27 15:07:21 UTC (rev 4937) @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Transactions; +using NHibernate.Dialect; +using NHibernate.Impl; +using NUnit.Framework; +using NHibernate.Criterion; + +namespace NHibernate.Test.NHSpecificTest.NH2077 +{ + [TestFixture] + public class Fixture : BugTestCase + { + + protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect) + { + return dialect is MsSql2000Dialect; + } + + [Test] + public void CanExecuteMultipleQueriesUsingNativeSQL() + { + using (var s = OpenSession()) + { + s.CreateSQLQuery( + @" +DELETE FROM Person WHERE Id = :userId; +UPDATE Person SET Id = :deletedUserId WHERE Id = :userId; +DELETE FROM Person WHERE Id = :userId; +") + .SetParameter("userId",1) + .SetParameter("deletedUserId", 1) + .ExecuteUpdate(); + } + } + + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Mappings.hbm.xml 2010-01-27 15:07:21 UTC (rev 4937) @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2077"> + + <class name="Person"> + <id name="Id"> + <generator class="increment" /> + </id> + <property name="Name"/> + + <set name="Children"> + <key column="ParentId"/> + <one-to-many class="Person"/> + </set> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2077/Model.cs 2010-01-27 15:07:21 UTC (rev 4937) @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2077 +{ + public class Person + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual ICollection<Person> Children { get; set; } + } + +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-27 14:40:36 UTC (rev 4936) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-27 15:07:21 UTC (rev 4937) @@ -700,6 +700,8 @@ <Compile Include="NHSpecificTest\NH2030\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2065\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2065\Model.cs" /> + <Compile Include="NHSpecificTest\NH2077\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2077\Model.cs" /> <Compile Include="NHSpecificTest\NH473\Child.cs" /> <Compile Include="NHSpecificTest\NH473\Fixture.cs" /> <Compile Include="NHSpecificTest\NH473\Parent.cs" /> @@ -2117,6 +2119,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2077\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2020\Mappings.hbm.xml" /> <EmbeddedResource Include="GhostProperty\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2065\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-01-27 15:58:58
|
Revision: 4940 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4940&view=rev Author: ayenderahien Date: 2010-01-27 15:58:40 +0000 (Wed, 27 Jan 2010) Log Message: ----------- NH-2074 - supporting unicode values in formula fields for SQL 2000 & up Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs trunk/nhibernate/src/NHibernate/SqlCommand/Template.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Model.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2010-01-27 15:19:39 UTC (rev 4939) +++ trunk/nhibernate/src/NHibernate/Dialect/Dialect.cs 2010-01-27 15:58:40 UTC (rev 4940) @@ -17,7 +17,7 @@ using NHibernate.SqlTypes; using NHibernate.Type; using NHibernate.Util; -using Environment=NHibernate.Cfg.Environment; +using Environment = NHibernate.Cfg.Environment; namespace NHibernate.Dialect { @@ -67,8 +67,8 @@ { standardAggregateFunctions["count"] = new CountQueryFunctionInfo(); standardAggregateFunctions["avg"] = new AvgQueryFunctionInfo(); - standardAggregateFunctions["max"] = new ClassicAggregateFunction("max",false); - standardAggregateFunctions["min"] = new ClassicAggregateFunction("min",false); + standardAggregateFunctions["max"] = new ClassicAggregateFunction("max", false); + standardAggregateFunctions["min"] = new ClassicAggregateFunction("min", false); standardAggregateFunctions["sum"] = new SumQueryFunctionInfo(); Extracter = new NoOpViolatedConstraintNameExtracter(); @@ -151,7 +151,7 @@ { dialectName = Environment.Properties[Environment.Dialect]; } - catch(Exception e) + catch (Exception e) { throw new HibernateException("The dialect was not set. Set the property 'dialect'.", e); } @@ -171,7 +171,7 @@ throw new ArgumentNullException("props"); string dialectName; if (props.TryGetValue(Environment.Dialect, out dialectName) == false) - throw new InvalidOperationException("Could not find the dialect in the configuration"); + throw new InvalidOperationException("Could not find the dialect in the configuration"); if (dialectName == null) { return GetDialect(); @@ -184,7 +184,7 @@ { try { - return (Dialect) Environment.BytecodeProvider.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(dialectName)); + return (Dialect)Environment.BytecodeProvider.ObjectsFactory.CreateInstance(ReflectHelper.ClassForName(dialectName)); } catch (Exception e) { @@ -270,7 +270,7 @@ /// <returns> The appropriate command. </returns> public virtual string SelectGUIDString { - get{throw new NotSupportedException("dialect does not support server side GUIDs generation.");} + get { throw new NotSupportedException("dialect does not support server side GUIDs generation."); } } /// <summary> Command used to create a table. </summary> @@ -307,7 +307,7 @@ /// </summary> public virtual string CreateTemporaryTablePostfix { - get{return string.Empty;} + get { return string.Empty; } } /// <summary> @@ -397,13 +397,13 @@ get { return String.Empty; } } - /// <summary> - /// The keyword used to create a primary key constraint - /// </summary> - public virtual string PrimaryKeyString - { - get { return "primary key"; } - } + /// <summary> + /// The keyword used to create a primary key constraint + /// </summary> + public virtual string PrimaryKeyString + { + get { return "primary key"; } + } #region database type mapping support @@ -415,7 +415,7 @@ /// <returns>The database type name used by ddl.</returns> public virtual string GetTypeName(SqlType sqlType) { - if (sqlType.LengthDefined || sqlType.PrecisionDefined) + if (sqlType.LengthDefined || sqlType.PrecisionDefined) { string resultWithLength = typeNames.Get(sqlType.DbType, sqlType.Length, sqlType.Precision, sqlType.Scale); if (resultWithLength != null) return resultWithLength; @@ -1473,7 +1473,7 @@ return (name[0] == OpenQuote && name[name.Length - 1] == CloseQuote); } - public virtual string Qualify(string catalog, string schema, string table) + public virtual string Qualify(string catalog, string schema, string table) { StringBuilder qualifiedName = new StringBuilder(); @@ -1533,8 +1533,8 @@ public virtual string QuoteForAliasName(string aliasName) { return IsQuoted(aliasName) ? - aliasName : - Quote(aliasName); + aliasName : + Quote(aliasName); } /// <summary> @@ -1554,8 +1554,8 @@ public virtual string QuoteForColumnName(string columnName) { return IsQuoted(columnName) ? - columnName : - Quote(columnName); + columnName : + Quote(columnName); } /// <summary> @@ -1574,8 +1574,8 @@ public virtual string QuoteForTableName(string tableName) { return IsQuoted(tableName) ? - tableName : - Quote(tableName); + tableName : + Quote(tableName); } /// <summary> @@ -1594,8 +1594,8 @@ public virtual string QuoteForSchemaName(string schemaName) { return IsQuoted(schemaName) ? - schemaName : - Quote(schemaName); + schemaName : + Quote(schemaName); } /// <summary> @@ -1963,7 +1963,8 @@ [Serializable] protected class CountQueryFunctionInfo : ClassicAggregateFunction { - public CountQueryFunctionInfo() : base("count",true) + public CountQueryFunctionInfo() + : base("count", true) { } @@ -1975,7 +1976,8 @@ [Serializable] protected class AvgQueryFunctionInfo : ClassicAggregateFunction { - public AvgQueryFunctionInfo() : base("avg",false) + public AvgQueryFunctionInfo() + : base("avg", false) { } @@ -2002,11 +2004,12 @@ return NHibernateUtil.Double; } } - + [Serializable] protected class SumQueryFunctionInfo : ClassicAggregateFunction { - public SumQueryFunctionInfo() : base("sum",false) + public SumQueryFunctionInfo() + : base("sum", false) { } @@ -2106,16 +2109,20 @@ } #endregion - /// <summary> - /// Supports splitting batches using GO T-SQL command - /// </summary> - /// <remarks> - /// Batches http://msdn.microsoft.com/en-us/library/ms175502.aspx - /// </remarks> - public virtual bool SupportsSqlBatches - { - get { return false; } - } + /// <summary> + /// Supports splitting batches using GO T-SQL command + /// </summary> + /// <remarks> + /// Batches http://msdn.microsoft.com/en-us/library/ms175502.aspx + /// </remarks> + public virtual bool SupportsSqlBatches + { + get { return false; } + } + public virtual bool IsKnownToken(string currentToken, string nextToken) + { + return false; + } } } Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2010-01-27 15:19:39 UTC (rev 4939) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2000Dialect.cs 2010-01-27 15:58:40 UTC (rev 4940) @@ -10,7 +10,7 @@ using NHibernate.SqlCommand; using NHibernate.Type; using NHibernate.Util; -using Environment=NHibernate.Cfg.Environment; +using Environment = NHibernate.Cfg.Environment; namespace NHibernate.Dialect { @@ -106,7 +106,7 @@ RegisterFunction("left", new SQLFunctionTemplate(NHibernateUtil.String, "left(?1, ?2)")); RegisterFunction("right", new SQLFunctionTemplate(NHibernateUtil.String, "right(?1, ?2)")); - RegisterFunction("locate", new StandardSQLFunction("charindex", NHibernateUtil.Int32)); + RegisterFunction("locate", new StandardSQLFunction("charindex", NHibernateUtil.Int32)); RegisterFunction("current_timestamp", new NoArgSQLFunction("getdate", NHibernateUtil.DateTime, true)); @@ -128,7 +128,7 @@ RegisterFunction("trim", new AnsiTrimEmulationFunction()); RegisterFunction("iif", new SQLFunctionTemplate(null, "case when ?1 then ?2 else ?3 end")); - RegisterFunction("replace", new StandardSafeSQLFunction("replace",NHibernateUtil.String, 3)); + RegisterFunction("replace", new StandardSafeSQLFunction("replace", NHibernateUtil.String, 3)); RegisterKeyword("top"); RegisterKeyword("integer"); @@ -496,12 +496,17 @@ get { return true; } } - public override bool SupportsSqlBatches - { - get - { - return true; - } - } + public override bool SupportsSqlBatches + { + get + { + return true; + } + } + + public override bool IsKnownToken(string currentToken, string nextToken) + { + return currentToken == "n" && nextToken == "'"; // unicode character + } } } Modified: trunk/nhibernate/src/NHibernate/SqlCommand/Template.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/Template.cs 2010-01-27 15:19:39 UTC (rev 4939) +++ trunk/nhibernate/src/NHibernate/SqlCommand/Template.cs 2010-01-27 15:58:40 UTC (rev 4940) @@ -312,6 +312,7 @@ Keywords.Contains(lcToken) || functionRegistry.HasFunction(lcToken) || dialect.Keywords.Contains(lcToken) || + dialect.IsKnownToken(lcToken, nextToken) || FunctionKeywords.Contains(lcToken); } Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Fixture.cs 2010-01-27 15:58:40 UTC (rev 4940) @@ -0,0 +1,25 @@ +using NHibernate.Dialect; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2074 +{ + [TestFixture] + public class Fixture : BugTestCase + { + + protected override bool AppliesTo(NHibernate.Dialect.Dialect dialect) + { + return dialect is MsSql2000Dialect; + } + + [Test] + public void CanQueryOnPropertyUsingUnicodeToken() + { + using (var s = OpenSession()) + { + s.CreateQuery("from Person").List(); + } + } + + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Mappings.hbm.xml 2010-01-27 15:58:40 UTC (rev 4940) @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2074"> + + <class name="Person"> + <id name="Id"> + <generator class="increment" /> + </id> + <property name="Name"/> + + <property name="CalculatedProperty" formula="(SELECT COUNT(*) FROM Person t WHERE t.Name = N'VALUE')" /> + + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2074/Model.cs 2010-01-27 15:58:40 UTC (rev 4940) @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2074 +{ + public class Person + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual int CalculatedProperty { get; set; } + } + +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-27 15:19:39 UTC (rev 4939) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-01-27 15:58:40 UTC (rev 4940) @@ -700,6 +700,8 @@ <Compile Include="NHSpecificTest\NH2030\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2065\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2065\Model.cs" /> + <Compile Include="NHSpecificTest\NH2074\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2074\Model.cs" /> <Compile Include="NHSpecificTest\NH2077\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2077\Model.cs" /> <Compile Include="NHSpecificTest\NH473\Child.cs" /> @@ -2119,6 +2121,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2074\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2077\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2020\Mappings.hbm.xml" /> <EmbeddedResource Include="GhostProperty\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-02-07 12:39:09
|
Revision: 4943 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4943&view=rev Author: ricbrown Date: 2010-02-07 12:15:51 +0000 (Sun, 07 Feb 2010) Log Message: ----------- Fix NH-2101 (Missing IsNotIn for WhereRestrictionOn) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2010-02-01 20:48:56 UTC (rev 4942) +++ trunk/nhibernate/src/NHibernate/Criterion/Lambda/QueryOverRestrictionBuilder.cs 2010-02-07 12:15:51 UTC (rev 4943) @@ -16,6 +16,15 @@ public QueryOverRestrictionBuilder(QueryOver<TRoot,TSubType> root, string propertyName) : base(root, propertyName) { } + public QueryOverRestrictionBuilder<TRoot,TSubType> Not + { + get + { + isNot = !isNot; + return this; + } + } + } public class IQueryOverRestrictionBuilder<TRoot,TSubType> : QueryOverRestrictionBuilderBase<IQueryOver<TRoot,TSubType>, TRoot, TSubType> @@ -24,6 +33,15 @@ public IQueryOverRestrictionBuilder(IQueryOver<TRoot,TSubType> root, string propertyName) : base(root, propertyName) { } + public IQueryOverRestrictionBuilder<TRoot,TSubType> Not + { + get + { + isNot = !isNot; + return this; + } + } + } public class QueryOverRestrictionBuilderBase<TReturn,TRoot,TSubType> @@ -33,23 +51,34 @@ { private TReturn root; private string propertyName; + private bool isNot; private object lo; - public LambdaBetweenBuilder(TReturn root, string propertyName, object lo) + public LambdaBetweenBuilder(TReturn root, string propertyName, bool isNot, object lo) { this.root = root; this.propertyName = propertyName; + this.isNot = isNot; this.lo = lo; } + private TReturn Add(ICriterion criterion) + { + if (isNot) + criterion = Restrictions.Not(criterion); + + return (TReturn)root.And(criterion); + } + public TReturn And(object hi) { - return (TReturn)root.And(Restrictions.Between(propertyName, lo, hi)); + return Add(Restrictions.Between(propertyName, lo, hi)); } } private TReturn root; private string propertyName; + protected bool isNot; /// <summary> /// Constructed with property name @@ -60,12 +89,20 @@ this.propertyName = propertyName; } + private TReturn Add(ICriterion criterion) + { + if (isNot) + criterion = Restrictions.Not(criterion); + + return (TReturn)root.And(criterion); + } + /// <summary> /// Apply a "between" constraint to the named property /// </summary> public LambdaBetweenBuilder IsBetween(object lo) { - return new LambdaBetweenBuilder(root, propertyName, lo); + return new LambdaBetweenBuilder(root, propertyName, isNot, lo); } /// <summary> @@ -73,7 +110,7 @@ /// </summary> public TReturn IsIn(ICollection values) { - return (TReturn)root.And(Restrictions.In(propertyName, values)); + return Add(Restrictions.In(propertyName, values)); } /// <summary> @@ -81,7 +118,7 @@ /// </summary> public TReturn IsIn(object[] values) { - return (TReturn)root.And(Restrictions.In(propertyName, values)); + return Add(Restrictions.In(propertyName, values)); } /// <summary> @@ -89,7 +126,7 @@ /// </summary> public TReturn IsInG<T>(ICollection<T> values) { - return (TReturn)root.And(Restrictions.InG(propertyName, values)); + return Add(Restrictions.InG(propertyName, values)); } /// <summary> @@ -97,7 +134,7 @@ /// </summary> public TReturn IsInsensitiveLike(object value) { - return (TReturn)root.And(Restrictions.InsensitiveLike(propertyName, value)); + return Add(Restrictions.InsensitiveLike(propertyName, value)); } /// <summary> @@ -105,7 +142,7 @@ /// </summary> public TReturn IsInsensitiveLike(string value, MatchMode matchMode) { - return (TReturn)root.And(Restrictions.InsensitiveLike(propertyName, value, matchMode)); + return Add(Restrictions.InsensitiveLike(propertyName, value, matchMode)); } /// <summary> @@ -113,7 +150,7 @@ /// </summary> public TReturn IsEmpty { - get { return (TReturn)root.And(Restrictions.IsEmpty(propertyName)); } + get { return Add(Restrictions.IsEmpty(propertyName)); } } /// <summary> @@ -121,7 +158,7 @@ /// </summary> public TReturn IsNotEmpty { - get { return (TReturn)root.And(Restrictions.IsNotEmpty(propertyName)); } + get { return Add(Restrictions.IsNotEmpty(propertyName)); } } /// <summary> @@ -129,7 +166,7 @@ /// </summary> public TReturn IsNull { - get { return (TReturn)root.And(Restrictions.IsNull(propertyName)); } + get { return Add(Restrictions.IsNull(propertyName)); } } /// <summary> @@ -137,7 +174,7 @@ /// </summary> public TReturn IsNotNull { - get { return (TReturn)root.And(Restrictions.IsNotNull(propertyName)); } + get { return Add(Restrictions.IsNotNull(propertyName)); } } /// <summary> @@ -145,7 +182,7 @@ /// </summary> public TReturn IsLike(object value) { - return (TReturn)root.And(Restrictions.Like(propertyName, value)); + return Add(Restrictions.Like(propertyName, value)); } /// <summary> @@ -153,7 +190,7 @@ /// </summary> public TReturn IsLike(string value, MatchMode matchMode) { - return (TReturn)root.And(Restrictions.Like(propertyName, value, matchMode)); + return Add(Restrictions.Like(propertyName, value, matchMode)); } /// <summary> @@ -161,7 +198,7 @@ /// </summary> public TReturn IsLike(string value, MatchMode matchMode, char? escapeChar) { - return (TReturn)root.And(Restrictions.Like(propertyName, value, matchMode, escapeChar)); + return Add(Restrictions.Like(propertyName, value, matchMode, escapeChar)); } } Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2010-02-01 20:48:56 UTC (rev 4942) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/RestrictionsFixture.cs 2010-02-07 12:15:51 UTC (rev 4943) @@ -112,6 +112,7 @@ CreateTestCriteria(typeof(Person), "personAlias") .Add(Restrictions.Between("Age", 18, 65)) .Add(Restrictions.Between("personAlias.Age", 18, 65)) + .Add(Restrictions.Not(Restrictions.Between("Age", 18, 65))) .Add(Restrictions.In("Name", new string[] { "name1", "name2", "name3" })) .Add(Restrictions.In("personAlias.Name", new ArrayList() { "name1", "name2", "name3" })) .Add(Restrictions.InG<int>("Age", new int[] { 1, 2, 3 })) @@ -123,13 +124,15 @@ .Add(Restrictions.IsNull("Name")) .Add(Restrictions.Like("Name", "%test%")) .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere)) - .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?')); + .Add(Restrictions.Like("Name", "test", MatchMode.Anywhere, '?')) + .Add(Restrictions.Not(Restrictions.Like("Name", "%test%"))); Person personAlias = null; var actual = CreateTestQueryOver<Person>(() => personAlias) .WhereRestrictionOn(p => p.Age).IsBetween(18).And(65) .WhereRestrictionOn(() => personAlias.Age).IsBetween(18).And(65) + .WhereRestrictionOn(p => p.Age).Not.IsBetween(18).And(65) .AndRestrictionOn(p => p.Name).IsIn(new string[] { "name1", "name2", "name3" }) .AndRestrictionOn(() => personAlias.Name).IsIn(new ArrayList() { "name1", "name2", "name3" }) .AndRestrictionOn(p => p.Age).IsInG<int>(new int[] { 1, 2, 3 }) @@ -141,7 +144,8 @@ .AndRestrictionOn(p => p.Name).IsNull .AndRestrictionOn(p => p.Name).IsLike("%test%") .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere) - .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere, '?'); + .AndRestrictionOn(p => p.Name).IsLike("test", MatchMode.Anywhere, '?') + .AndRestrictionOn(p => p.Name).Not.IsLike("%test%"); AssertCriteriaAreEqual(expected, actual); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-02-16 22:50:26
|
Revision: 4944 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4944&view=rev Author: ricbrown Date: 2010-02-16 22:50:19 +0000 (Tue, 16 Feb 2010) Log Message: ----------- Fix NH-1981 (Multiple SQL parameters generated for same HQL parameter) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs trunk/nhibernate/src/NHibernate/Loader/Loader.cs trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -50,19 +50,6 @@ { return base.GetLimitString(querySqlString, offset, last); } - // we have to do this in order to support parameters in order clause, the foramt - // that sql 2005 uses for paging means that we move the parameters around, which means, - // that positions are lost, so we record them before making any changes. - // NH-1528 - int parameterPositon = 0; - foreach (var part in querySqlString.Parts) - { - Parameter param = part as Parameter; - if (param == null) - continue; - param.OriginalPositionInQuery = parameterPositon; - parameterPositon += 1; - } int fromIndex = GetFromIndex(querySqlString); SqlString select = querySqlString.Substring(0, fromIndex); Modified: trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -56,27 +56,8 @@ return; } - string name; + string name = formatter.GetParameterName(parameter.ParameterPosition ?? parameterIndex); - if (queryIndexToNumberOfPreceedingParameters.Count == 0) - { - // there's only one query... no need to worry about indexes of parameters of previous queries - name = formatter.GetParameterName(parameter.OriginalPositionInQuery ?? parameterIndex); - } - else - { - // multiple queries... in case the parameters were switched around (for SQL paging for instance) we need - // to keep the number of preceeding parameters (in previous queries of the batch) into account - if (parameter.OriginalPositionInQuery != null) - { - name = formatter.GetParameterName(GetNumberOfPreceedingParameters() + parameter.OriginalPositionInQuery.Value); - } - else - { - name = formatter.GetParameterName(parameterIndex); - } - } - parameterIndex++; result.Append(name); } Modified: trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Engine/Query/NativeSQLQueryPlan.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -86,7 +86,7 @@ { queryParameters.ProcessFilters(customQuery.SQL, session); SqlString sql = queryParameters.FilteredSQL; - SqlType[] sqlTypes = GetParameterTypes(queryParameters, session); + SqlType[] sqlTypes = queryParameters.PrepareParameterTypes(sql, session.Factory, GetNamedParameterLocs, 0, false, false); IDbCommand ps = session.Batcher.PrepareCommand(CommandType.Text, sql, sqlTypes); @@ -102,7 +102,7 @@ // The responsibility of parameter binding was entirely moved to QueryParameters // to deal with positionslParameter+NamedParameter+ParameterOfFilters - queryParameters.BindParameters(ps, GetNamedParameterLocs, 0, session); + queryParameters.BindParameters(ps, 0, session); result = session.Batcher.ExecuteNonQuery(ps); } finally @@ -125,52 +125,5 @@ return result; } - - private SqlType[] GetParameterTypes(QueryParameters parameters, ISessionImplementor session) - { - List<IType> paramTypeList = new List<IType>(); - int span = 0; - - foreach (IType type in parameters.PositionalParameterTypes) - { - paramTypeList.Add(type); - span += type.GetColumnSpan(session.Factory); - } - - if (parameters.NamedParameters != null && parameters.NamedParameters.Count > 0) - { - int offset = paramTypeList.Count; - - // convert the named parameters to an array of types - foreach (KeyValuePair<string, TypedValue> e in parameters.NamedParameters) - { - string name = e.Key; - TypedValue typedval = e.Value; - int[] locs = GetNamedParameterLocs(name); - span += typedval.Type.GetColumnSpan(session.Factory) * locs.Length; - - for (int i = 0; i < locs.Length; i++) - { - ArrayHelper.SafeSetValue(paramTypeList, locs[i] + offset, typedval.Type); - } - } - } - return ConvertITypesToSqlTypes(paramTypeList, span, session); - } - - private static SqlType[] ConvertITypesToSqlTypes(IList<IType> nhTypes, int totalSpan, ISessionImplementor session) - { - SqlType[] result = new SqlType[totalSpan]; - - int index = 0; - foreach (IType type in nhTypes) - { - int span = type.SqlTypes(session.Factory).Length; - Array.Copy(type.SqlTypes(session.Factory), 0, result, index, span); - index += span; - } - - return result; - } } } Modified: trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Engine/QueryParameters.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -6,6 +6,7 @@ using NHibernate.Hql.Classic; using NHibernate.Impl; using NHibernate.SqlCommand; +using NHibernate.SqlTypes; using NHibernate.Transform; using NHibernate.Type; using NHibernate.Util; @@ -392,31 +393,162 @@ processedSQL = result.ToSqlString(); } - public int BindParameters(IDbCommand command, GetNamedParameterLocations getNamedParameterLocations, int start, - ISessionImplementor session) + private IList<Parameter> ResetParameterLocations(SqlString sqlString) { + IList<Parameter> sqlParameters = new List<Parameter>(); + + foreach (object sqlParameter in sqlString.Parts) + { + if (sqlParameter is Parameter) + { + Parameter parameter = (Parameter)sqlParameter; + parameter.ParameterPosition = null; + sqlParameters.Add(parameter); + } + } + + return sqlParameters; + } + + private void SetParameterLocation(IList<Parameter> sqlParameters, int parameterIndex, int sqlLocation, int span) + { + int i = 0; + while (i < span) + { + sqlParameters[sqlLocation + i].ParameterPosition = parameterIndex + i; + i++; + } + } + + private SqlType[] ConvertITypesToSqlTypes(List<IType> nhTypes, ISessionFactoryImplementor factory, int totalSpan) + { + SqlType[] result = new SqlType[totalSpan]; + + int index = 0; + foreach (IType type in nhTypes) + { + int span = type.SqlTypes(factory).Length; + Array.Copy(type.SqlTypes(factory), 0, result, index, span); + index += span; + } + + return result; + } + + public SqlType[] PrepareParameterTypes(SqlString sqlString, ISessionFactoryImplementor factory, GetNamedParameterLocations getNamedParameterLocations, int startParameterIndex, bool addLimit, bool addOffset) + { + List<IType> paramTypeList = new List<IType>(); + int parameterIndex = 0; + int totalSpan = 0; + + IList<Parameter> sqlParameters = ResetParameterLocations(sqlString); + + for (int index = 0; index < PositionalParameterTypes.Length; index++) + { + IType type = PositionalParameterTypes[index]; + ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type); + + int location = PositionalParameterLocations[index]; + location = FindAdjustedParameterLocation(location); + int span = type.GetColumnSpan(factory); + SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span); + + totalSpan += span; + parameterIndex++; + } + + for (int index = 0; index < FilteredParameterTypes.Count; index++) + { + IType type = FilteredParameterTypes[index]; + ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, type); + + int location = FilteredParameterLocations[index]; + int span = type.GetColumnSpan(factory); + SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span); + + totalSpan += span; + parameterIndex++; + } + + if (NamedParameters != null && NamedParameters.Count > 0) + { + // convert the named parameters to an array of types + foreach (KeyValuePair<string, TypedValue> namedParameter in NamedParameters) + { + TypedValue typedval = namedParameter.Value; + ArrayHelper.SafeSetValue(paramTypeList, parameterIndex, typedval.Type); + + int span = typedval.Type.GetColumnSpan(factory); + string name = namedParameter.Key; + int[] locs = getNamedParameterLocations(name); + for (int i = 0; i < locs.Length; i++) + { + int location = locs[i]; + location = FindAdjustedParameterLocation(location); + + // can still clash with positional parameters + // could consider throwing an exception to locate problem (NH-1098) + while ((location < sqlParameters.Count) && (sqlParameters[location].ParameterPosition != null)) + location++; + + SetParameterLocation(sqlParameters, startParameterIndex + parameterIndex, location, span); + } + + totalSpan += span; + parameterIndex++; + } + } + + if (addLimit && factory.Dialect.SupportsVariableLimit) + { + if (factory.Dialect.BindLimitParametersFirst) + { + paramTypeList.Insert(0, NHibernateUtil.Int32); + if (addOffset) + { + paramTypeList.Insert(0, NHibernateUtil.Int32); + } + } + else + { + paramTypeList.Add(NHibernateUtil.Int32); + if (addOffset) + { + paramTypeList.Add(NHibernateUtil.Int32); + } + } + + totalSpan += addOffset ? 2 : 1; + } + + return ConvertITypesToSqlTypes(paramTypeList, factory, totalSpan); + } + + public int BindParameters(IDbCommand command, int start, ISessionImplementor session) + { + int location = 0; var values = new List<object>(); var types = new List<IType>(); var sources = new List<string>(); for (int i = 0; i < _positionalParameterLocations.Length; i++) { - int location = FindAdjustedParameterLocation(_positionalParameterLocations[i]); object value = _positionalParameterValues[i]; IType type = _positionalParameterTypes[i]; ArrayHelper.SafeSetValue(values, location, value); ArrayHelper.SafeSetValue(types, location, type); ArrayHelper.SafeSetValue(sources, location, "Positional" + i); + location++; } for (int i = 0; i < filteredParameterLocations.Count; i++) { - int location = filteredParameterLocations[i]; object value = filteredParameterValues[i]; IType type = filteredParameterTypes[i]; ArrayHelper.SafeSetValue(values, location, value); ArrayHelper.SafeSetValue(types, location, type); ArrayHelper.SafeSetValue(sources, location, "Filter" + i); + location++; } if ((_namedParameters != null) && (_namedParameters.Count > 0)) @@ -425,22 +557,10 @@ { string name = namedParameter.Key; TypedValue typedval = namedParameter.Value; - int[] locations = getNamedParameterLocations(name); - for (int i = 0; i < locations.Length; i++) - { - int location = FindAdjustedParameterLocation(locations[i]); - - // can still clash with positional parameters - // could consider throwing an exception to locate problem (NH-1098) - while ((location < types.Count) && (types[location] != null)) - { - location++; - } - - ArrayHelper.SafeSetValue(values, location, typedval.Value); - ArrayHelper.SafeSetValue(types, location, typedval.Type); - ArrayHelper.SafeSetValue(sources, location, "name" + i); - } + ArrayHelper.SafeSetValue(values, location, typedval.Value); + ArrayHelper.SafeSetValue(types, location, typedval.Type); + ArrayHelper.SafeSetValue(sources, location, "name_" + name); + location++; } } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Impl/MultiCriteriaImpl.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -180,7 +180,7 @@ translators.Add(translator); QueryParameters queryParameters = translator.GetQueryParameters(); parameters.Add(queryParameters); - SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters); + SqlCommandInfo commandInfo = loader.GetQueryStringAndTypes(session, queryParameters, types.Count); sqlString = sqlString.Append(commandInfo.Text) .Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator) .Append(Environment.NewLine); @@ -339,7 +339,7 @@ for (int i = 0; i < loaders.Count; i++) { QueryParameters parameter = parameters[i]; - colIndex += parameter.BindParameters(command, loaders[i].GetNamedParameterLocs, colIndex, session); + colIndex += parameter.BindParameters(command, colIndex, session); } return colIndex; } Modified: trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Impl/MultiQueryImpl.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -616,7 +616,7 @@ translators.Add(translator); parameters.Add(queryParameters); queryParameters = GetFilteredQueryParameters(queryParameters, translator); - SqlCommandInfo commandInfo = translator.Loader.GetQueryStringAndTypes(session, queryParameters); + SqlCommandInfo commandInfo = translator.Loader.GetQueryStringAndTypes(session, queryParameters, types.Count); sqlString = sqlString.Append(commandInfo.Text).Append(session.Factory.ConnectionProvider.Driver.MultipleQueriesSeparator).Append(Environment.NewLine); types.AddRange(commandInfo.ParameterTypes); } @@ -668,7 +668,7 @@ { IQueryTranslator translator = Translators[i]; QueryParameters parameter = Parameters[i]; - colIndex += parameter.BindParameters(command, translator.Loader.GetNamedParameterLocs, colIndex, session); + colIndex += parameter.BindParameters(command, colIndex, session); } return colIndex; } Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using Remotion.Data.Linq.Parsing; @@ -23,12 +24,17 @@ protected override Expression VisitConstantExpression(ConstantExpression expression) { - if (!typeof(IQueryable).IsAssignableFrom(expression.Type)) + if (!typeof(IQueryable).IsAssignableFrom(expression.Type) && !IsNullObject(expression)) { _parameters.Add(expression, new NamedParameter("p" + (_parameters.Count + 1), expression.Value, NHibernateUtil.GuessType(expression.Type))); } return base.VisitConstantExpression(expression); } + + private bool IsNullObject(ConstantExpression expression) + { + return expression.Type == typeof(Object) && expression.Value == null; + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -1106,6 +1106,8 @@ bool useOffset = hasFirstRow && useLimit && dialect.SupportsLimitOffset; // TODO NH bool callable = queryParameters.Callable; + SqlType[] parameterTypes = queryParameters.PrepareParameterTypes(sqlString, Factory, GetNamedParameterLocs, 0, useLimit, useOffset); + if (useLimit) { sqlString = @@ -1116,8 +1118,7 @@ // TODO NH: Callable for SP -> PrepareCallableQueryCommand IDbCommand command = - session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, - GetParameterTypes(queryParameters, useLimit, useOffset)); + session.Batcher.PrepareQueryCommand(CommandType.Text, sqlString, parameterTypes); try { @@ -1263,7 +1264,7 @@ // NH Different behavior: // The responsibility of parameter binding was entirely moved to QueryParameters // to deal with positionslParameter+NamedParameter+ParameterOfFilters - return queryParameters.BindParameters(statement, GetNamedParameterLocs, 0, session); + return queryParameters.BindParameters(statement, 0, session); } public virtual int[] GetNamedParameterLocs(string name) @@ -1683,7 +1684,7 @@ #region NHibernate specific - public virtual SqlCommandInfo GetQueryStringAndTypes(ISessionImplementor session, QueryParameters parameters) + public virtual SqlCommandInfo GetQueryStringAndTypes(ISessionImplementor session, QueryParameters parameters, int startParameterIndex) { SqlString sqlString = ProcessFilters(parameters, session); Dialect.Dialect dialect = session.Factory.Dialect; @@ -1693,6 +1694,8 @@ bool hasFirstRow = GetFirstRow(selection) > 0; bool useOffset = hasFirstRow && useLimit && dialect.SupportsLimitOffset; + SqlType[] sqlTypes = parameters.PrepareParameterTypes(sqlString, Factory, GetNamedParameterLocs, startParameterIndex, useLimit, useOffset); + if (useLimit) { sqlString = @@ -1700,97 +1703,9 @@ } sqlString = PreprocessSQL(sqlString, parameters, dialect); - return new SqlCommandInfo(sqlString, GetParameterTypes(parameters, useLimit, useOffset)); + return new SqlCommandInfo(sqlString, sqlTypes); } - protected SqlType[] ConvertITypesToSqlTypes(List<IType> nhTypes, int totalSpan) - { - SqlType[] result = new SqlType[totalSpan]; - - int index = 0; - foreach (IType type in nhTypes) - { - int span = type.SqlTypes(Factory).Length; - Array.Copy(type.SqlTypes(Factory), 0, result, index, span); - index += span; - } - - return result; - } - - /// <returns><see cref="IList" /> of <see cref="IType" /></returns> - protected SqlType[] GetParameterTypes(QueryParameters parameters, bool addLimit, bool addOffset) - { - List<IType> paramTypeList = new List<IType>(); - int span = 0; - - for (int index = 0; index < parameters.PositionalParameterTypes.Length; index++) - { - int location = parameters.PositionalParameterLocations[index]; - location = parameters.FindAdjustedParameterLocation(location); - IType type = parameters.PositionalParameterTypes[index]; - ArrayHelper.SafeSetValue(paramTypeList, location, type); - span += type.GetColumnSpan(Factory); - } - - for (int index = 0; index < parameters.FilteredParameterTypes.Count; index++) - { - int location = parameters.FilteredParameterLocations[index]; - IType type = parameters.FilteredParameterTypes[index]; - ArrayHelper.SafeSetValue(paramTypeList, location, type); - span += type.GetColumnSpan(Factory); - } - - if (parameters.NamedParameters != null && parameters.NamedParameters.Count > 0) - { - // convert the named parameters to an array of types - foreach (KeyValuePair<string, TypedValue> namedParameter in parameters.NamedParameters) - { - string name = namedParameter.Key; - TypedValue typedval = namedParameter.Value; - int[] locs = GetNamedParameterLocs(name); - span += typedval.Type.GetColumnSpan(Factory) * locs.Length; - - for (int i = 0; i < locs.Length; i++) - { - int location = locs[i]; - location = parameters.FindAdjustedParameterLocation(location); - - // can still clash with positional parameters - // could consider throwing an exception to locate problem (NH-1098) - while ((location < paramTypeList.Count) && (paramTypeList[location] != null)) - location++; - - ArrayHelper.SafeSetValue(paramTypeList, location, typedval.Type); - } - } - } - - if (addLimit && Factory.Dialect.SupportsVariableLimit) - { - if (Factory.Dialect.BindLimitParametersFirst) - { - paramTypeList.Insert(0, NHibernateUtil.Int32); - if (addOffset) - { - paramTypeList.Insert(0, NHibernateUtil.Int32); - } - } - else - { - paramTypeList.Add(NHibernateUtil.Int32); - if (addOffset) - { - paramTypeList.Add(NHibernateUtil.Int32); - } - } - - span += addOffset ? 2 : 1; - } - - return ConvertITypesToSqlTypes(paramTypeList, span); - } - #endregion } } Modified: trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs =================================================================== --- trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate/SqlCommand/Parameter.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -10,16 +10,13 @@ [Serializable] public class Parameter { - /// <summary> + /// <summary> /// We need to know what the position of the parameter was in a query /// before we rearranged the query. - /// This is used only by dialects that rearrange the query, unfortunately, - /// the MS SQL 2005 dialect have to re shuffle the query (and ruin positional parameter - /// support) because the SQL 2005 and 2008 SQL dialects have a completely broken - /// support for paging, which is just a tad less important than SELECT. - /// See NH-1528 - /// </summary> - public int? OriginalPositionInQuery; + /// This is the ADO parameter position that this SqlString parameter is + /// bound to. The SqlString can be safely rearranged once this is set. + /// </summary> + public int? ParameterPosition; /// <summary> /// Used as a placeholder when parsing HQL or SQL queries. Modified: trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate.Test/Linq/RegresstionTests.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -1,5 +1,6 @@ using System.Linq; using NUnit.Framework; +using NHibernate.Test.Linq.Entities; namespace NHibernate.Test.Linq { @@ -10,7 +11,7 @@ /// http://aspzone.com/tech/nhibernate-linq-troubles/ /// </summary> [Test] - public void HierarchicalQueries() + public void HierarchicalQueries_InlineConstant() { var children = from s in db.Role where s.ParentRole != null @@ -24,5 +25,32 @@ Assert.AreEqual(2, roots.Count()); } + + [Test] + public void HierarchicalQueries_Variable() + { + Role testRole = null; + var children = from s in db.Role + where s.ParentRole != testRole + select s; + + Assert.AreEqual(0, children.Count()); + + var roots = from s in db.Role + where s.ParentRole == testRole + select s; + + Assert.AreEqual(2, roots.Count()); + } + [Test] + public void CanUseNullConstantAndRestriction() + { + var roots = from s in db.Role + where s.ParentRole == null + && s.Name == "Admin" + select s; + + Assert.AreEqual(1, roots.Count()); + } } } \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Fixture.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Text; +using NHibernate.Cfg; +using NHibernate.Tool.hbm2ddl; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1981 +{ + [TestFixture] + public class Fixture : BugTestCase + { + [Test] + public void CanGroupWithParameter() + { + using (ISession s = OpenSession()) + using (ITransaction tx = s.BeginTransaction()) + { + s.Save(new Article() { Longitude = 90 }); + s.Save(new Article() { Longitude = 90 }); + s.Save(new Article() { Longitude = 120 }); + + IList<double> quotients = + s.CreateQuery( + @"select (Longitude / :divisor) + from Article + group by (Longitude / :divisor)") + .SetDouble("divisor", 30) + .List<double>(); + + Assert.That(quotients.Count, Is.EqualTo(2)); + Assert.That(quotients[0], Is.EqualTo(3)); + Assert.That(quotients[1], Is.EqualTo(4)); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Mappings.hbm.xml 2010-02-16 22:50:19 UTC (rev 4944) @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + namespace="NHibernate.Test.NHSpecificTest.NH1981" + assembly="NHibernate.Test"> + + <class name="Article"> + <id name="Id"> + <generator class="hilo" /> + </id> + <property name="Longitude" /> + </class> +</hibernate-mapping> + + Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1981/Model.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH1981 +{ + public class Article + { + public virtual int Id { get; set; } + public virtual double Longitude { get; set; } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-02-16 22:50:19 UTC (rev 4944) @@ -663,6 +663,8 @@ <Compile Include="NHSpecificTest\NH1978\AliasTest.cs" /> <Compile Include="NHSpecificTest\NH1978\Employee.cs" /> <Compile Include="NHSpecificTest\NH1978\_401k.cs" /> + <Compile Include="NHSpecificTest\NH1981\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1981\Model.cs" /> <Compile Include="NHSpecificTest\NH1989\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1989\Model.cs" /> <Compile Include="NHSpecificTest\NH2009\Fixture.cs" /> @@ -2121,6 +2123,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1981\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2074\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2077\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2020\Mappings.hbm.xml" /> Modified: trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs 2010-02-07 12:15:51 UTC (rev 4943) +++ trunk/nhibernate/src/NHibernate.Test/SqlCommandTest/SqlStringFixture.cs 2010-02-16 22:50:19 UTC (rev 4944) @@ -375,8 +375,8 @@ Assert.AreEqual(parameterString1, parameterString2); Assert.AreNotSame(parameterString1, parameterString2); - parameters1[0].OriginalPositionInQuery = 231; - Assert.IsNull(parameters2[0].OriginalPositionInQuery); + parameters1[0].ParameterPosition = 231; + Assert.IsNull(parameters2[0].ParameterPosition); } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <aye...@us...> - 2010-03-03 15:54:42
|
Revision: 4951 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4951&view=rev Author: ayenderahien Date: 2010-03-03 15:54:34 +0000 (Wed, 03 Mar 2010) Log Message: ----------- Fixing NH-2113 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Type/ComponentType.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Model.cs Modified: trunk/nhibernate/src/NHibernate/Type/ComponentType.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2010-03-02 20:55:46 UTC (rev 4950) +++ trunk/nhibernate/src/NHibernate/Type/ComponentType.cs 2010-03-03 15:54:34 UTC (rev 4951) @@ -23,8 +23,9 @@ private readonly FetchMode?[] joinedFetch; private readonly bool isKey; protected internal EntityModeToTuplizerMapping tuplizerMapping; + private bool overridesGetHashCode; - public override SqlType[] SqlTypes(IMapping mapping) + public override SqlType[] SqlTypes(IMapping mapping) { //Not called at runtime so doesn't matter if its slow :) SqlType[] sqlTypes = new SqlType[GetColumnSpan(mapping)]; @@ -72,6 +73,11 @@ } tuplizerMapping = metamodel.TuplizerMapping; + var tuplizer = tuplizerMapping.GetTuplizerOrNull(EntityMode.Poco); + if(tuplizer !=null) + { + overridesGetHashCode = ReflectHelper.OverridesGetHashCode(tuplizer.MappedClass); + } } /// <summary></summary> @@ -100,6 +106,8 @@ public override int GetHashCode(object x, EntityMode entityMode, ISessionFactoryImplementor factory) { + if (overridesGetHashCode) + return x.GetHashCode(); return GetHashCode(x, entityMode); } Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Fixture.cs 2010-03-03 15:54:34 UTC (rev 4951) @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Transactions; +using NHibernate.Dialect; +using NHibernate.Impl; +using NUnit.Framework; +using NHibernate.Criterion; + +namespace NHibernate.Test.NHSpecificTest.NH2113 +{ + [TestFixture] + public class Fixture : BugTestCase + { + + [Test] + public void ShouldNotEagerLoadKeyManyToOneWhenOverridingGetHashCode() + { + using (var s = OpenSession()) + using(var tx = s.BeginTransaction()) + { + var grp = new Group(); + s.Save(grp); + + var broker = new Broker{Key = new Key{BankId = 1, Id = -1}}; + s.Save(broker); + + var load = new Loan {Broker = broker, Group = grp, Name = "money!!!"}; + s.Save(load); + + tx.Commit(); + } + + bool isInitialized; + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + var loan = s.CreateCriteria<Loan>() + .UniqueResult<Loan>(); + + isInitialized = NHibernateUtil.IsInitialized(loan.Broker); + + tx.Commit(); + } + + + using (var s = OpenSession()) + using (var tx = s.BeginTransaction()) + { + s.Delete("from System.Object"); + + tx.Commit(); + } + + Assert.False(isInitialized); + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Mappings.hbm.xml 2010-03-03 15:54:34 UTC (rev 4951) @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2113"> + + <class name="Loan"> + <composite-id> + <key-many-to-one name="Broker" class="Broker"> + <column name="BrokerID"/> + <column name="BankID"/> + </key-many-to-one> + <key-many-to-one name="Group" + column="GroupID" class="Group"/> + </composite-id> + <property name="Name" /> + </class> + + <class name="Group" table="Groups"> + <id name="Id" column="GroupID"> + <generator class="increment"/> + </id> + </class> + + <class name="Broker"> + <composite-id name="Key"> + <key-property name="Id" + column="BrokerID"/> + <key-property name="BankId"/> + </composite-id> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Model.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Model.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2113/Model.cs 2010-03-03 15:54:34 UTC (rev 4951) @@ -0,0 +1,89 @@ +namespace NHibernate.Test.NHSpecificTest.NH2113 +{ + public class Loan + { + public virtual Broker Broker{ get; set;} + public virtual Group Group { get; set; } + public virtual string Name { get; set; } + + public virtual bool Equals(Loan other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(other.Broker, Broker) && Equals(other.Group, Group); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof (Loan)) return false; + return Equals((Loan) obj); + } + + public override int GetHashCode() + { + unchecked + { + return ((Broker != null ? Broker.Key.GetHashCode() : 0)*397) ^ (Group != null ? Group.GetHashCode() : 0); + } + } + } + + public class Group + { + public virtual int Id { get; set; } + } + public class Broker + { + public virtual Key Key { get; set; } + + public virtual bool Equals(Broker other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Equals(other.Key, Key); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof (Broker)) return false; + return Equals((Broker) obj); + } + + public override int GetHashCode() + { + return (Key != null ? Key.GetHashCode() : 0); + } + } + public class Key + { + public int Id { get; set; } + public int BankId { get; set; } + + public virtual bool Equals(Key other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return other.Id == Id && other.BankId == BankId; + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + if (obj.GetType() != typeof (Key)) return false; + return Equals((Key) obj); + } + + public override int GetHashCode() + { + unchecked + { + return (Id*397) ^ BankId; + } + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-03-02 20:55:46 UTC (rev 4950) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-03-03 15:54:34 UTC (rev 4951) @@ -707,6 +707,8 @@ <Compile Include="NHSpecificTest\NH2074\Model.cs" /> <Compile Include="NHSpecificTest\NH2077\Fixture.cs" /> <Compile Include="NHSpecificTest\NH2077\Model.cs" /> + <Compile Include="NHSpecificTest\NH2113\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2113\Model.cs" /> <Compile Include="NHSpecificTest\NH473\Child.cs" /> <Compile Include="NHSpecificTest\NH473\Fixture.cs" /> <Compile Include="NHSpecificTest\NH473\Parent.cs" /> @@ -2124,6 +2126,7 @@ <EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" /> <EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH2113\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1981\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2074\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2077\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-03-06 22:49:28
|
Revision: 4953 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4953&view=rev Author: ricbrown Date: 2010-03-06 22:49:21 +0000 (Sat, 06 Mar 2010) Log Message: ----------- Added QueryOverTransformer. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Added Paths: ----------- trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -12,7 +12,7 @@ { [Serializable] - public class QueryOver + public abstract class QueryOver { protected ICriteria criteria; @@ -40,10 +40,12 @@ get { return new DetachedCriteria(impl, impl); } } + public abstract object Clone(); + } [Serializable] - public class QueryOver<TRoot> : QueryOver, IQueryOver<TRoot> + public abstract class QueryOver<TRoot> : QueryOver, IQueryOver<TRoot> { private IList<TRoot> List() @@ -177,6 +179,11 @@ this.criteria = criteria; } + public override object Clone() + { + return new QueryOver<TRoot,TRoot>((CriteriaImpl)criteria.Clone()); + } + public QueryOver<TRoot,TSubType> And(Expression<Func<TSubType, bool>> expression) { return Add(expression); @@ -290,6 +297,12 @@ return new QueryOverOrderBuilder<TRoot,TSubType>(this, path); } + public QueryOver<TRoot,TSubType> ClearOrders() + { + criteria.ClearOrders(); + return this; + } + public QueryOver<TRoot,TSubType> Skip(int firstResult) { criteria.SetFirstResult(firstResult); @@ -620,6 +633,9 @@ IQueryOverOrderBuilder<TRoot,TSubType> IQueryOver<TRoot,TSubType>.ThenBy(Expression<Func<object>> path) { return new IQueryOverOrderBuilder<TRoot,TSubType>(this, path); } + IQueryOver<TRoot,TSubType> IQueryOver<TRoot, TSubType>.ClearOrders() + { return ClearOrders(); } + IQueryOver<TRoot,TSubType> IQueryOver<TRoot,TSubType>.Skip(int firstResult) { return Skip(firstResult); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -22,7 +22,7 @@ /// .List(); /// </code> /// </remarks> - public interface IQueryOver<TRoot> + public interface IQueryOver<TRoot> : ICloneable { /// <summary> /// Access the underlying ICriteria @@ -241,6 +241,11 @@ IQueryOverOrderBuilder<TRoot,TSubType> ThenBy(Expression<Func<object>> path); /// <summary> + /// Clear all orders from the query. + /// </summary> + IQueryOver<TRoot, TSubType> ClearOrders(); + + /// <summary> /// Set the first result to be retrieved /// </summary> /// <param name="firstResult"></param> Modified: trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/Impl/CriteriaImpl.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -460,8 +460,12 @@ projection = projectionList; } - projectionCriteria = this; - SetResultTransformer(CriteriaSpecification.Projection); + if (projection != null) + { + projectionCriteria = this; + SetResultTransformer(CriteriaSpecification.Projection); + } + return this; } Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-03-06 22:49:21 UTC (rev 4953) @@ -830,6 +830,7 @@ <Compile Include="Hql\Ast\ANTLR\Util\NodeTraverser.cs" /> <Compile Include="Param\VersionTypeSeedParameterSpecification.cs" /> <Compile Include="Proxy\AbstractProxyFactory.cs" /> + <Compile Include="QueryOverTransformer.cs" /> <Compile Include="SqlCommand\InsertSelect.cs" /> <Compile Include="Tool\hbm2ddl\SchemaMetadataUpdater.cs" /> <Compile Include="Tool\hbm2ddl\ScriptSplitter.cs" /> Added: trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs (rev 0) +++ trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -0,0 +1,54 @@ +using NHibernate.Criterion; +using NHibernate.Engine; +using NHibernate.Impl; + +namespace NHibernate +{ + /// <summary> + /// Transforms QueryOver queries + /// </summary> + public static class QueryOverTransformer + { + ///<summary> + /// Returns a clone of the original QueryOver, which will return the count + /// of rows that are returned by the original QueryOver query. + ///</summary> + public static QueryOver<T,T> TransformToRowCount<T>(QueryOver<T> query) + { + QueryOver<T,T> clonedQuery = (QueryOver<T,T>)query.Clone(); + return (QueryOver<T,T>)TransformToRowCount((IQueryOver<T>)clonedQuery); + } + + ///<summary> + /// Returns a clone of the original IQueryOver, which will return the count + /// of rows that are returned by the original IQueryOver query. + ///</summary> + public static IQueryOver<T,T> TransformToRowCount<T>(IQueryOver<T> query) + { + IQueryOver<T,T> clonedQuery = (IQueryOver<T,T>)query.Clone(); + + return + clonedQuery + .ClearOrders() + .Skip(0) + .Take(RowSelection.NoValue) + .Select(Projections.RowCount()); + } + + /// <summary> + /// Creates an exact clone of the IQueryOver + /// </summary> + public static IQueryOver<T,T> Clone<T>(IQueryOver<T> query) + { + return (IQueryOver<T,T>)query.Clone(); + } + + /// <summary> + /// Creates an exact clone of the QueryOver + /// </summary> + public static QueryOver<T,T> Clone<T>(QueryOver<T> query) + { + return (QueryOver<T,T>)query.Clone(); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-03 17:29:11 UTC (rev 4952) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-06 22:49:21 UTC (rev 4953) @@ -483,6 +483,75 @@ AssertCriteriaAreEqual(expected, actual); } + [Test] + public void CloneIQueryOver() + { + IQueryOver<Person> expected = + CreateTestQueryOver<Person>() + .Where(p => p.Name == "test") + .Select(p => p.Name); + + IQueryOver<Person> actual = QueryOverTransformer.Clone(expected); + + Assert.That(actual, Is.Not.SameAs(expected)); + Assert.That(actual.UnderlyingCriteria, Is.Not.SameAs(expected.UnderlyingCriteria)); + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual.UnderlyingCriteria); + } + + [Test] + public void CloneIQueryOverWithSubType() + { + IQueryOver<Person,Child> expected = + CreateTestQueryOver<Person>() + .JoinQueryOver(p => p.Children); + + IQueryOver<Person,Person> actual = QueryOverTransformer.Clone(expected); + + ICriteria expectedCriteria = expected.UnderlyingCriteria.GetCriteriaByAlias("this"); + + AssertCriteriaAreEqual(expectedCriteria, actual); + } + + [Test] + public void CloneQueryOver() + { + QueryOver<Person> expected = + QueryOver.Of<Person>() + .Where(p => p.Name == "test") + .Select(p => p.Name); + + QueryOver<Person> actual = QueryOverTransformer.Clone(expected); + + Assert.That(actual, Is.Not.SameAs(expected)); + Assert.That(actual.UnderlyingCriteria, Is.Not.SameAs(expected.UnderlyingCriteria)); + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual.UnderlyingCriteria); + } + + [Test] + public void TransformQueryOverToRowCount() + { + QueryOver<Person> expected = + QueryOver.Of<Person>() + .Where(p => p.Name == "test") + .JoinQueryOver(p => p.Children) + .Where((Child c) => c.Age == 5) + .Select(Projections.RowCount()); + + QueryOver<Person> actual = + QueryOver.Of<Person>() + .Where(p => p.Name == "test") + .JoinQueryOver(p => p.Children) + .Where((Child c) => c.Age == 5) + .OrderBy(c => c.Age).Asc + .Skip(20) + .Take(10); + + expected = QueryOverTransformer.Clone(expected); + actual = QueryOverTransformer.TransformToRowCount(actual); + + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-03-07 09:47:51
|
Revision: 4954 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4954&view=rev Author: ricbrown Date: 2010-03-07 09:47:45 +0000 (Sun, 07 Mar 2010) Log Message: ----------- Moved QueryOverTransformer methods into the IQueryOver interface, and dropped ICloneable. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate/NHibernate.csproj trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Removed Paths: ------------- trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-06 22:49:21 UTC (rev 4953) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-07 09:47:45 UTC (rev 4954) @@ -40,8 +40,6 @@ get { return new DetachedCriteria(impl, impl); } } - public abstract object Clone(); - } [Serializable] @@ -107,6 +105,28 @@ } /// <summary> + /// Clones the QueryOver, clears the orders and paging, and projects the RowCount + /// </summary> + /// <returns></returns> + public QueryOver<TRoot,TRoot> ToRowCountQuery() + { + return + Clone() + .ClearOrders() + .Skip(0) + .Take(RowSelection.NoValue) + .Select(Projections.RowCount()); + } + + /// <summary> + /// Creates an exact clone of the QueryOver + /// </summary> + public QueryOver<TRoot,TRoot> Clone() + { + return new QueryOver<TRoot,TRoot>((CriteriaImpl)criteria.Clone()); + } + + /// <summary> /// Method to allow comparison of detached query in Lambda expression /// e.g., p => p.Name == myQuery.As<string> /// </summary> @@ -127,6 +147,9 @@ IList<U> IQueryOver<TRoot>.List<U>() { return List<U>(); } + int IQueryOver<TRoot>.RowCount() + { return ToRowCountQuery().SingleOrDefault<int>(); } + TRoot IQueryOver<TRoot>.SingleOrDefault() { return SingleOrDefault(); } @@ -145,6 +168,9 @@ IFutureValue<U> IQueryOver<TRoot>.FutureValue<U>() { return FutureValue<U>(); } + IQueryOver<TRoot,TRoot> IQueryOver<TRoot>.Clone() + { return Clone(); } + } /// <summary> @@ -179,11 +205,6 @@ this.criteria = criteria; } - public override object Clone() - { - return new QueryOver<TRoot,TRoot>((CriteriaImpl)criteria.Clone()); - } - public QueryOver<TRoot,TSubType> And(Expression<Func<TSubType, bool>> expression) { return Add(expression); Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-06 22:49:21 UTC (rev 4953) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-07 09:47:45 UTC (rev 4954) @@ -22,7 +22,7 @@ /// .List(); /// </code> /// </remarks> - public interface IQueryOver<TRoot> : ICloneable + public interface IQueryOver<TRoot> { /// <summary> /// Access the underlying ICriteria @@ -42,6 +42,12 @@ IList<U> List<U>(); /// <summary> + /// Clones the QueryOver, removes orders and paging, projects the row-count + /// for the query and returns the Single() result + /// </summary> + int RowCount(); + + /// <summary> /// Convenience method to return a single instance that matches /// the query, or null if the query returns no results. /// </summary> @@ -84,6 +90,11 @@ /// </summary> IFutureValue<U> FutureValue<U>(); + /// <summary> + /// Creates an exact clone of the IQueryOver + /// </summary> + IQueryOver<TRoot,TRoot> Clone(); + } /// <summary> Modified: trunk/nhibernate/src/NHibernate/NHibernate.csproj =================================================================== --- trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-03-06 22:49:21 UTC (rev 4953) +++ trunk/nhibernate/src/NHibernate/NHibernate.csproj 2010-03-07 09:47:45 UTC (rev 4954) @@ -830,7 +830,6 @@ <Compile Include="Hql\Ast\ANTLR\Util\NodeTraverser.cs" /> <Compile Include="Param\VersionTypeSeedParameterSpecification.cs" /> <Compile Include="Proxy\AbstractProxyFactory.cs" /> - <Compile Include="QueryOverTransformer.cs" /> <Compile Include="SqlCommand\InsertSelect.cs" /> <Compile Include="Tool\hbm2ddl\SchemaMetadataUpdater.cs" /> <Compile Include="Tool\hbm2ddl\ScriptSplitter.cs" /> Deleted: trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs =================================================================== --- trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs 2010-03-06 22:49:21 UTC (rev 4953) +++ trunk/nhibernate/src/NHibernate/QueryOverTransformer.cs 2010-03-07 09:47:45 UTC (rev 4954) @@ -1,54 +0,0 @@ -using NHibernate.Criterion; -using NHibernate.Engine; -using NHibernate.Impl; - -namespace NHibernate -{ - /// <summary> - /// Transforms QueryOver queries - /// </summary> - public static class QueryOverTransformer - { - ///<summary> - /// Returns a clone of the original QueryOver, which will return the count - /// of rows that are returned by the original QueryOver query. - ///</summary> - public static QueryOver<T,T> TransformToRowCount<T>(QueryOver<T> query) - { - QueryOver<T,T> clonedQuery = (QueryOver<T,T>)query.Clone(); - return (QueryOver<T,T>)TransformToRowCount((IQueryOver<T>)clonedQuery); - } - - ///<summary> - /// Returns a clone of the original IQueryOver, which will return the count - /// of rows that are returned by the original IQueryOver query. - ///</summary> - public static IQueryOver<T,T> TransformToRowCount<T>(IQueryOver<T> query) - { - IQueryOver<T,T> clonedQuery = (IQueryOver<T,T>)query.Clone(); - - return - clonedQuery - .ClearOrders() - .Skip(0) - .Take(RowSelection.NoValue) - .Select(Projections.RowCount()); - } - - /// <summary> - /// Creates an exact clone of the IQueryOver - /// </summary> - public static IQueryOver<T,T> Clone<T>(IQueryOver<T> query) - { - return (IQueryOver<T,T>)query.Clone(); - } - - /// <summary> - /// Creates an exact clone of the QueryOver - /// </summary> - public static QueryOver<T,T> Clone<T>(QueryOver<T> query) - { - return (QueryOver<T,T>)query.Clone(); - } - } -} Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2010-03-06 22:49:21 UTC (rev 4953) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs 2010-03-07 09:47:45 UTC (rev 4954) @@ -262,6 +262,45 @@ } } + [Test] + public void RowCount() + { + using (ISession s = OpenSession()) + using (ITransaction t = s.BeginTransaction()) + { + s.Save(new Person() { Name = "Name 1", Age = 1 } + .AddChild(new Child() { Nickname = "Name 1.1", Age = 1})); + + s.Save(new Person() { Name = "Name 2", Age = 2 } + .AddChild(new Child() { Nickname = "Name 2.1", Age = 3})); + + s.Save(new Person() { Name = "Name 3", Age = 3 } + .AddChild(new Child() { Nickname = "Name 3.1", Age = 2})); + + s.Save(new Person() { Name = "Name 4", Age = 4 } + .AddChild(new Child() { Nickname = "Name 4.1", Age = 4})); + + t.Commit(); + } + + using (ISession s = OpenSession()) + { + IQueryOver<Person> query = + s.QueryOver<Person>() + .JoinQueryOver(p => p.Children) + .OrderBy(c => c.Age).Desc + .Skip(2) + .Take(1); + + IList<Person> results = query.List(); + int rowCount = query.RowCount(); + + Assert.That(results.Count, Is.EqualTo(1)); + Assert.That(results[0].Name, Is.EqualTo("Name 3")); + Assert.That(rowCount, Is.EqualTo(4)); + } + } + } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-06 22:49:21 UTC (rev 4953) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-07 09:47:45 UTC (rev 4954) @@ -491,7 +491,7 @@ .Where(p => p.Name == "test") .Select(p => p.Name); - IQueryOver<Person> actual = QueryOverTransformer.Clone(expected); + IQueryOver<Person> actual = expected.Clone(); Assert.That(actual, Is.Not.SameAs(expected)); Assert.That(actual.UnderlyingCriteria, Is.Not.SameAs(expected.UnderlyingCriteria)); @@ -505,7 +505,7 @@ CreateTestQueryOver<Person>() .JoinQueryOver(p => p.Children); - IQueryOver<Person,Person> actual = QueryOverTransformer.Clone(expected); + IQueryOver<Person,Person> actual = expected.Clone(); ICriteria expectedCriteria = expected.UnderlyingCriteria.GetCriteriaByAlias("this"); @@ -520,38 +520,13 @@ .Where(p => p.Name == "test") .Select(p => p.Name); - QueryOver<Person> actual = QueryOverTransformer.Clone(expected); + QueryOver<Person> actual = expected.Clone(); Assert.That(actual, Is.Not.SameAs(expected)); Assert.That(actual.UnderlyingCriteria, Is.Not.SameAs(expected.UnderlyingCriteria)); AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual.UnderlyingCriteria); } - [Test] - public void TransformQueryOverToRowCount() - { - QueryOver<Person> expected = - QueryOver.Of<Person>() - .Where(p => p.Name == "test") - .JoinQueryOver(p => p.Children) - .Where((Child c) => c.Age == 5) - .Select(Projections.RowCount()); - - QueryOver<Person> actual = - QueryOver.Of<Person>() - .Where(p => p.Name == "test") - .JoinQueryOver(p => p.Children) - .Where((Child c) => c.Age == 5) - .OrderBy(c => c.Age).Asc - .Skip(20) - .Take(10); - - expected = QueryOverTransformer.Clone(expected); - actual = QueryOverTransformer.TransformToRowCount(actual); - - AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual); - } - } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2010-03-07 10:16:15
|
Revision: 4955 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4955&view=rev Author: ricbrown Date: 2010-03-07 10:16:09 +0000 (Sun, 07 Mar 2010) Log Message: ----------- Added ToRowCountQuery method to interface to allow access to the query without performing execution. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs trunk/nhibernate/src/NHibernate/IQueryOver.cs trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs Modified: trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-07 09:47:45 UTC (rev 4954) +++ trunk/nhibernate/src/NHibernate/Criterion/QueryOver.cs 2010-03-07 10:16:09 UTC (rev 4955) @@ -147,6 +147,9 @@ IList<U> IQueryOver<TRoot>.List<U>() { return List<U>(); } + IQueryOver<TRoot,TRoot> IQueryOver<TRoot>.ToRowCountQuery() + { return ToRowCountQuery(); } + int IQueryOver<TRoot>.RowCount() { return ToRowCountQuery().SingleOrDefault<int>(); } Modified: trunk/nhibernate/src/NHibernate/IQueryOver.cs =================================================================== --- trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-07 09:47:45 UTC (rev 4954) +++ trunk/nhibernate/src/NHibernate/IQueryOver.cs 2010-03-07 10:16:09 UTC (rev 4955) @@ -42,9 +42,14 @@ IList<U> List<U>(); /// <summary> - /// Clones the QueryOver, removes orders and paging, projects the row-count - /// for the query and returns the Single() result + /// Clones the QueryOver, removes orders and paging, and projects the row-count + /// for the query /// </summary> + IQueryOver<TRoot,TRoot> ToRowCountQuery(); + + /// <summary> + /// Short for ToRowCountQuery().SingleOrDefault() + /// </summary> int RowCount(); /// <summary> Modified: trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-07 09:47:45 UTC (rev 4954) +++ trunk/nhibernate/src/NHibernate.Test/Criteria/Lambda/QueryOverFixture.cs 2010-03-07 10:16:09 UTC (rev 4955) @@ -527,6 +527,31 @@ AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual.UnderlyingCriteria); } + [Test] + public void TransformQueryOverToRowCount() + { + IQueryOver<Person> expected = + CreateTestQueryOver<Person>() + .Where(p => p.Name == "test") + .JoinQueryOver(p => p.Children) + .Where((Child c) => c.Age == 5) + .Select(Projections.RowCount()); + + IQueryOver<Person> actual = + CreateTestQueryOver<Person>() + .Where(p => p.Name == "test") + .JoinQueryOver(p => p.Children) + .Where((Child c) => c.Age == 5) + .OrderBy(c => c.Age).Asc + .Skip(20) + .Take(10); + + expected = expected.Clone(); + actual = actual.ToRowCountQuery(); + + AssertCriteriaAreEqual(expected.UnderlyingCriteria, actual); + } + } } \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |