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