Skip to content

Commit 9746b30

Browse files
committed
Fix NH-2302
SVN: trunk@5174
1 parent 232d648 commit 9746b30

File tree

8 files changed

+248
-12
lines changed

8 files changed

+248
-12
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
using NUnit.Framework;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH2302
4+
{
5+
[TestFixture]
6+
public class Fixture : BugTestCase
7+
{
8+
protected override void OnTearDown()
9+
{
10+
CleanUp();
11+
12+
base.OnTearDown();
13+
}
14+
15+
[Test]
16+
public void StringHugeLength()
17+
{
18+
int id;
19+
// buildup a string the exceed the mapping
20+
string str = GetFixedLengthString12000();
21+
22+
using (ISession sess = OpenSession())
23+
using (ITransaction tx = sess.BeginTransaction())
24+
{
25+
// create and save the entity
26+
StringLengthEntity entity = new StringLengthEntity();
27+
entity.StringHugeLength = str;
28+
sess.Save(entity);
29+
tx.Commit();
30+
id = entity.ID;
31+
}
32+
33+
using (ISession sess = OpenSession())
34+
using (ITransaction tx = sess.BeginTransaction())
35+
{
36+
StringLengthEntity loaded = sess.Get<StringLengthEntity>(id);
37+
Assert.IsNotNull(loaded);
38+
Assert.AreEqual(12000, loaded.StringHugeLength.Length);
39+
Assert.AreEqual(str, loaded.StringHugeLength);
40+
tx.Commit();
41+
}
42+
}
43+
44+
[Test, Ignore("Not supported without specify the string length.")]
45+
public void StringSqlType()
46+
{
47+
int id;
48+
// buildup a string the exceed the mapping
49+
string str = GetFixedLengthString12000();
50+
51+
using (ISession sess = OpenSession())
52+
using (ITransaction tx = sess.BeginTransaction())
53+
{
54+
// create and save the entity
55+
StringLengthEntity entity = new StringLengthEntity();
56+
entity.StringSqlType = str;
57+
sess.Save(entity);
58+
tx.Commit();
59+
id = entity.ID;
60+
}
61+
62+
using (ISession sess = OpenSession())
63+
using (ITransaction tx = sess.BeginTransaction())
64+
{
65+
StringLengthEntity loaded = sess.Get<StringLengthEntity>(id);
66+
Assert.IsNotNull(loaded);
67+
Assert.AreEqual(12000, loaded.StringSqlType.Length);
68+
Assert.AreEqual(str, loaded.StringSqlType);
69+
tx.Commit();
70+
}
71+
}
72+
73+
[Test]
74+
public void BlobSqlType()
75+
{
76+
int id;
77+
// buildup a string the exceed the mapping
78+
string str = GetFixedLengthString12000();
79+
80+
using (ISession sess = OpenSession())
81+
using (ITransaction tx = sess.BeginTransaction())
82+
{
83+
// create and save the entity
84+
StringLengthEntity entity = new StringLengthEntity();
85+
entity.BlobSqlType = str;
86+
sess.Save(entity);
87+
tx.Commit();
88+
id = entity.ID;
89+
}
90+
91+
using (ISession sess = OpenSession())
92+
using (ITransaction tx = sess.BeginTransaction())
93+
{
94+
StringLengthEntity loaded = sess.Get<StringLengthEntity>(id);
95+
Assert.IsNotNull(loaded);
96+
Assert.AreEqual(12000, loaded.BlobSqlType.Length);
97+
Assert.AreEqual(str, loaded.BlobSqlType);
98+
tx.Commit();
99+
}
100+
}
101+
102+
[Test]
103+
public void BlobWithLength()
104+
{
105+
int id;
106+
// buildup a string the exceed the mapping
107+
string str = GetFixedLengthString12000();
108+
109+
using (ISession sess = OpenSession())
110+
using (ITransaction tx = sess.BeginTransaction())
111+
{
112+
// create and save the entity
113+
StringLengthEntity entity = new StringLengthEntity();
114+
entity.BlobLength = str;
115+
sess.Save(entity);
116+
tx.Commit();
117+
id = entity.ID;
118+
}
119+
120+
using (ISession sess = OpenSession())
121+
using (ITransaction tx = sess.BeginTransaction())
122+
{
123+
StringLengthEntity loaded = sess.Get<StringLengthEntity>(id);
124+
Assert.IsNotNull(loaded);
125+
Assert.AreEqual(12000, loaded.BlobLength.Length);
126+
Assert.AreEqual(str, loaded.BlobLength);
127+
tx.Commit();
128+
}
129+
}
130+
131+
[Test]
132+
public void BlobWithoutLength()
133+
{
134+
int id;
135+
// buildup a string the exceed the mapping
136+
string str = GetFixedLengthString12000();
137+
138+
using (ISession sess = OpenSession())
139+
using (ITransaction tx = sess.BeginTransaction())
140+
{
141+
// create and save the entity
142+
StringLengthEntity entity = new StringLengthEntity();
143+
entity.Blob = str;
144+
sess.Save(entity);
145+
tx.Commit();
146+
id = entity.ID;
147+
}
148+
149+
using (ISession sess = OpenSession())
150+
using (ITransaction tx = sess.BeginTransaction())
151+
{
152+
StringLengthEntity loaded = sess.Get<StringLengthEntity>(id);
153+
Assert.IsNotNull(loaded);
154+
Assert.AreEqual(12000, loaded.Blob.Length);
155+
Assert.AreEqual(str, loaded.Blob);
156+
tx.Commit();
157+
}
158+
}
159+
160+
private void CleanUp()
161+
{
162+
using (ISession session = OpenSession())
163+
using (ITransaction tx = session.BeginTransaction())
164+
{
165+
session.Delete("from StringLengthEntity");
166+
tx.Commit();
167+
}
168+
}
169+
170+
private static string GetFixedLengthString12000()
171+
{
172+
return new string('a', 12000);
173+
}
174+
175+
}
176+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" default-cascade="all-delete-orphan">
3+
<class name="NHibernate.Test.NHSpecificTest.NH2302.StringLengthEntity, NHibernate.Test" table="StringLengthEntity"
4+
lazy="false">
5+
<id name="ID" access="nosetter.pascalcase-m" column="ID" type="Int32" >
6+
<generator class="native" />
7+
</id>
8+
<!-- this generates an nvarchar(255) -->
9+
<property name="StringDefault" column="StringDefault" type="string" />
10+
<!-- this generates an nvarchar(50) -->
11+
<property name="StringFixedLength" column="StringFixedLength" type="string" length="50" />
12+
<!-- this generates an nvarchar(max) but it operate a truncation on reading and writing, in NHib 2.1 this was -->
13+
<property name="StringHugeLength" column="StringHugeLength" type="string" length="10000" />
14+
<!-- this generates an nvarchar(max) but it operate a truncation reading and writing to the default string length (4000) -->
15+
<property name="StringSqlType" type="string">
16+
<column name="StringSqlType" sql-type="nvarchar(max)" />
17+
</property>
18+
<!-- this generates an nvarchar(255) otherwise reading and writing seem to be ok -->
19+
<property name="Blob" column="Blob" type="StringClob" />
20+
<!-- this generates an nvarchar(max) but it operate a truncation on reading and writing (same as StringHugeLength) -->
21+
<property name="BlobLength" column="BlobLength" type="StringClob" length="15000" />
22+
<!-- this mapping works! for generation, writing and reading -->
23+
<property name="BlobSqlType" type="StringClob" >
24+
<column name="BlobSqlType" sql-type="nvarchar(max)" />
25+
</property>
26+
</class>
27+
</hibernate-mapping>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
namespace NHibernate.Test.NHSpecificTest.NH2302
2+
{
3+
public class StringLengthEntity
4+
{
5+
private int mID = 0;
6+
public int ID
7+
{
8+
get { return mID; }
9+
}
10+
11+
public string StringDefault { get; set; }
12+
13+
public string StringFixedLength { get; set; }
14+
15+
public string StringHugeLength { get; set; }
16+
17+
public string StringSqlType { get; set; }
18+
19+
public string Blob { get; set; }
20+
21+
public string BlobLength { get; set; }
22+
23+
public string BlobSqlType { get; set; }
24+
}
25+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,8 @@
471471
<Compile Include="NHSpecificTest\NH2287\Fixture.cs" />
472472
<Compile Include="NHSpecificTest\NH2293\Fixture.cs" />
473473
<Compile Include="NHSpecificTest\NH2294\Fixture.cs" />
474+
<Compile Include="NHSpecificTest\NH2302\Fixture.cs" />
475+
<Compile Include="NHSpecificTest\NH2302\StringLengthEntity.cs" />
474476
<Compile Include="NHSpecificTest\NH2303\Fixture.cs" />
475477
<Compile Include="NHSpecificTest\NH2303\Model.cs" />
476478
<Compile Include="TypesTest\CharClass.cs" />
@@ -2261,6 +2263,7 @@
22612263
<EmbeddedResource Include="CollectionTest\NullableValueTypeElementMapFixture.hbm.xml" />
22622264
<EmbeddedResource Include="DriverTest\EntityForMs2008.hbm.xml" />
22632265
<Content Include="DynamicEntity\package.html" />
2266+
<EmbeddedResource Include="NHSpecificTest\NH2302\Mappings.hbm.xml" />
22642267
<EmbeddedResource Include="NHSpecificTest\NH2303\Mappings.hbm.xml" />
22652268
<EmbeddedResource Include="NHSpecificTest\NH2287\Mappings.hbm.xml" />
22662269
<EmbeddedResource Include="NHSpecificTest\NH2266\Mappings.hbm.xml" />

src/NHibernate.sln

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ EndProject
2323
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NHibernate.TestDatabaseSetup", "NHibernate.TestDatabaseSetup\NHibernate.TestDatabaseSetup.csproj", "{BEEC1564-6FB6-49F7-BBE5-8EBD2F0F6E8A}"
2424
EndProject
2525
Global
26+
GlobalSection(TestCaseManagementSettings) = postSolution
27+
CategoryFile = NHibernate.vsmdi
28+
EndGlobalSection
2629
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2730
Debug|Any CPU = Debug|Any CPU
2831
Release|Any CPU = Release|Any CPU

src/NHibernate/Dialect/MsSql2000Dialect.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace NHibernate.Dialect
4040
/// </remarks>
4141
public class MsSql2000Dialect : Dialect
4242
{
43+
public const int MaxSizeForLengthLimitedStrings = 4000;
4344
/// <summary></summary>
4445
public MsSql2000Dialect()
4546
{
@@ -65,9 +66,9 @@ public MsSql2000Dialect()
6566
RegisterColumnType(DbType.Int64, "BIGINT");
6667
RegisterColumnType(DbType.Single, "REAL"); //synonym for FLOAT(24)
6768
RegisterColumnType(DbType.StringFixedLength, "NCHAR(255)");
68-
RegisterColumnType(DbType.StringFixedLength, 4000, "NCHAR($l)");
69+
RegisterColumnType(DbType.StringFixedLength, MaxSizeForLengthLimitedStrings, "NCHAR($l)");
6970
RegisterColumnType(DbType.String, "NVARCHAR(255)");
70-
RegisterColumnType(DbType.String, 4000, "NVARCHAR($l)");
71+
RegisterColumnType(DbType.String, MaxSizeForLengthLimitedStrings, "NVARCHAR($l)");
7172
RegisterColumnType(DbType.String, 1073741823, "NTEXT");
7273
RegisterColumnType(DbType.Time, "DATETIME");
7374

src/NHibernate/Driver/SqlClientDriver.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Data;
22
using System.Data.SqlClient;
33
using NHibernate.AdoNet;
4+
using NHibernate.Dialect;
45
using NHibernate.SqlCommand;
56
using NHibernate.SqlTypes;
67

@@ -123,14 +124,7 @@ private static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sq
123124
break;
124125
case DbType.String:
125126
case DbType.StringFixedLength:
126-
if (sqlType is StringClobSqlType)
127-
{
128-
dbParam.Size = MaxStringClobSize;
129-
}
130-
else
131-
{
132-
dbParam.Size = MaxStringSize;
133-
}
127+
dbParam.Size = IsText(dbParam, sqlType) ? MaxStringClobSize : MaxStringSize;
134128
break;
135129
case DbType.DateTime2:
136130
dbParam.Size = MaxDateTime2;
@@ -141,12 +135,18 @@ private static void SetDefaultParameterSize(IDbDataParameter dbParam, SqlType sq
141135
}
142136
}
143137

138+
private static bool IsText(IDbDataParameter dbParam, SqlType sqlType)
139+
{
140+
return (sqlType is StringClobSqlType) || (sqlType.LengthDefined && sqlType.Length > MsSql2000Dialect.MaxSizeForLengthLimitedStrings &&
141+
(DbType.String == dbParam.DbType || DbType.StringFixedLength == dbParam.DbType));
142+
}
143+
144144
private static void SetVariableLengthParameterSize(IDbDataParameter dbParam, SqlType sqlType)
145145
{
146146
SetDefaultParameterSize(dbParam, sqlType);
147147

148148
// Override the defaults using data from SqlType.
149-
if (sqlType.LengthDefined)
149+
if (sqlType.LengthDefined && !IsText(dbParam, sqlType))
150150
{
151151
dbParam.Size = sqlType.Length;
152152
}

src/NHibernate/SqlTypes/StringClobSqlType.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ public class StringClobSqlType : StringSqlType
2626
/// <summary>
2727
/// Initializes a new instance of the <see cref="StringClobSqlType"/> class.
2828
/// </summary>
29-
public StringClobSqlType() : base()
29+
public StringClobSqlType()
30+
: base(int.MaxValue / 2)
3031
{
3132
}
3233

0 commit comments

Comments
 (0)