Skip to content

Commit bad7e99

Browse files
bahusoidfredericDelaporte
authored andcommitted
Fix collection lazy loading with composite keys on subclass columns
1 parent f36baa5 commit bad7e99

File tree

6 files changed

+304
-5
lines changed

6 files changed

+304
-5
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System.Linq;
12+
using NHibernate.Linq;
13+
using NUnit.Framework;
14+
15+
namespace NHibernate.Test.NHSpecificTest.NH2174
16+
{
17+
using System.Threading.Tasks;
18+
[TestFixture]
19+
public class CollectionWithSubclassesAndCompositeIdFixtureAsync : BugTestCase
20+
{
21+
protected override void OnSetUp()
22+
{
23+
using (var session = OpenSession())
24+
using (var transaction = session.BeginTransaction())
25+
{
26+
var doc = new Document {Id_Base = 1, Id_Doc = 2};
27+
session.Save(doc);
28+
session.Save(new DocumentDetailDocument {Id_Base = 1, Id_Doc = 2, Id_Item = 1, ReferencedDocument = doc});
29+
30+
transaction.Commit();
31+
}
32+
}
33+
34+
protected override void OnTearDown()
35+
{
36+
using (var session = OpenSession())
37+
using (var transaction = session.BeginTransaction())
38+
{
39+
session.Delete("from System.Object");
40+
transaction.Commit();
41+
}
42+
}
43+
44+
[KnownBug("Not fixed yet")]
45+
[Test]
46+
public async Task LinqFetchAsync()
47+
{
48+
using (var session = OpenSession())
49+
{
50+
var result = await ((from e in session.Query<Document>().Fetch(x => x.RefferedDetails)
51+
select e).FirstOrDefaultAsync());
52+
53+
Assert.That(result.RefferedDetails, Has.Count.EqualTo(1));
54+
}
55+
}
56+
57+
[KnownBug("Not fixed yet")]
58+
[Test]
59+
public async Task QueryOverFetchAsync()
60+
{
61+
using (var session = OpenSession())
62+
{
63+
var result = await (session.QueryOver<Document>().Fetch(SelectMode.Fetch, x => x.RefferedDetails).SingleOrDefaultAsync());
64+
Assert.That(result.RefferedDetails, Has.Count.EqualTo(1));
65+
}
66+
}
67+
68+
[Test]
69+
public async Task LazyLoadAsync()
70+
{
71+
using (var session = OpenSession())
72+
{
73+
var result = await ((from e in session.Query<Document>()
74+
select e).FirstAsync());
75+
Assert.That(result.RefferedDetails.Count, Is.EqualTo(1));
76+
}
77+
}
78+
}
79+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System.Collections.Generic;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH2174
4+
{
5+
class DocumentDetail
6+
{
7+
private int _id_item;
8+
9+
protected bool Equals(DocumentDetail other)
10+
{
11+
return _id_item == other._id_item && _Version == other._Version && _id_Doc == other._id_Doc && _id_base == other._id_base;
12+
}
13+
14+
public override bool Equals(object obj)
15+
{
16+
if (ReferenceEquals(null, obj)) return false;
17+
if (ReferenceEquals(this, obj)) return true;
18+
if (obj.GetType() != this.GetType()) return false;
19+
return Equals((DocumentDetail) obj);
20+
}
21+
22+
public override int GetHashCode()
23+
{
24+
unchecked
25+
{
26+
var hashCode = _id_item;
27+
hashCode = (hashCode * 397) ^ _Version;
28+
hashCode = (hashCode * 397) ^ _id_Doc;
29+
hashCode = (hashCode * 397) ^ _id_base;
30+
return hashCode;
31+
}
32+
}
33+
34+
private int _Version;
35+
private int _id_Doc;
36+
private int _id_base;
37+
38+
public int Id_Item
39+
{
40+
get => _id_item;
41+
set => _id_item = value;
42+
}
43+
44+
public int Version
45+
{
46+
get => _Version;
47+
set => _Version = value;
48+
}
49+
50+
public int Id_Doc
51+
{
52+
get => _id_Doc;
53+
set => _id_Doc = value;
54+
}
55+
56+
public int Id_Base
57+
{
58+
get => _id_base;
59+
set => _id_base = value;
60+
}
61+
}
62+
63+
class Document
64+
{
65+
protected bool Equals(Document other)
66+
{
67+
return _id_Doc == other._id_Doc && _id_base == other._id_base;
68+
}
69+
70+
public override bool Equals(object obj)
71+
{
72+
if (ReferenceEquals(null, obj)) return false;
73+
if (ReferenceEquals(this, obj)) return true;
74+
if (obj.GetType() != this.GetType()) return false;
75+
return Equals((Document) obj);
76+
}
77+
78+
public override int GetHashCode()
79+
{
80+
unchecked
81+
{
82+
return (_id_Doc * 397) ^ _id_base;
83+
}
84+
}
85+
86+
private int _id_Doc;
87+
private int _id_base;
88+
public virtual IList<DocumentDetailDocument> RefferedDetails { get; set; } = new List<DocumentDetailDocument>();
89+
90+
public int Id_Doc
91+
{
92+
get => _id_Doc;
93+
set => _id_Doc = value;
94+
}
95+
96+
public int Id_Base
97+
{
98+
get => _id_base;
99+
set => _id_base = value;
100+
}
101+
}
102+
103+
class DocumentDetailDocument : DocumentDetail
104+
{
105+
public virtual Document ReferencedDocument { get; set; }
106+
}
107+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System.Linq;
2+
using NHibernate.Linq;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.NHSpecificTest.NH2174
6+
{
7+
[TestFixture]
8+
public class CollectionWithSubclassesAndCompositeIdFixture : BugTestCase
9+
{
10+
protected override void OnSetUp()
11+
{
12+
using (var session = OpenSession())
13+
using (var transaction = session.BeginTransaction())
14+
{
15+
var doc = new Document {Id_Base = 1, Id_Doc = 2};
16+
session.Save(doc);
17+
session.Save(new DocumentDetailDocument {Id_Base = 1, Id_Doc = 2, Id_Item = 1, ReferencedDocument = doc});
18+
19+
transaction.Commit();
20+
}
21+
}
22+
23+
protected override void OnTearDown()
24+
{
25+
using (var session = OpenSession())
26+
using (var transaction = session.BeginTransaction())
27+
{
28+
session.Delete("from System.Object");
29+
transaction.Commit();
30+
}
31+
}
32+
33+
[KnownBug("Not fixed yet")]
34+
[Test]
35+
public void LinqFetch()
36+
{
37+
using (var session = OpenSession())
38+
{
39+
var result = (from e in session.Query<Document>().Fetch(x => x.RefferedDetails)
40+
select e).FirstOrDefault();
41+
42+
Assert.That(result.RefferedDetails, Has.Count.EqualTo(1));
43+
}
44+
}
45+
46+
[KnownBug("Not fixed yet")]
47+
[Test]
48+
public void QueryOverFetch()
49+
{
50+
using (var session = OpenSession())
51+
{
52+
var result = session.QueryOver<Document>().Fetch(SelectMode.Fetch, x => x.RefferedDetails).SingleOrDefault();
53+
Assert.That(result.RefferedDetails, Has.Count.EqualTo(1));
54+
}
55+
}
56+
57+
[Test]
58+
public void LazyLoad()
59+
{
60+
using (var session = OpenSession())
61+
{
62+
var result = (from e in session.Query<Document>()
63+
select e).First();
64+
Assert.That(result.RefferedDetails.Count, Is.EqualTo(1));
65+
}
66+
}
67+
}
68+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
3+
namespace="NHibernate.Test.NHSpecificTest.NH2174">
4+
5+
<class lazy="false" table="o_Details" dynamic-update="true" name="DocumentDetail">
6+
<cache usage="nonstrict-read-write" />
7+
<composite-id>
8+
<key-property name="_id_item" column="id_item" access="field" />
9+
<key-property name="_Version" column="Version" access="field" />
10+
<key-property name="_id_Doc" column="id_Doc" access="field" />
11+
<key-property name="_id_base" column="id_base" access="field" />
12+
</composite-id>
13+
<discriminator column="id_type" />
14+
15+
</class>
16+
17+
<subclass discriminator-value="102" extends="DocumentDetail" lazy="false" name="DocumentDetailDocument">
18+
<join table="o_DetailsDoc" fetch="select">
19+
<key>
20+
<column name="id_item" />
21+
<column name="Version" />
22+
<column name="id_Doc" />
23+
<column name="id_base" />
24+
</key>
25+
<many-to-one name="ReferencedDocument" not-null="true" fetch="select" update="false" lazy="false">
26+
<column name="id_Doc_detail" not-null="true" />
27+
<column name="id_base_detail" not-null="true" />
28+
</many-to-one>
29+
</join>
30+
</subclass>
31+
32+
<class lazy="false" table="o_DocumentInstances" dynamic-update="true" name="Document">
33+
<cache usage="nonstrict-read-write" />
34+
<composite-id>
35+
<key-property name="_id_Doc" column="id_Doc" access="field"/>
36+
<key-property name="_id_base" column="id_base" access="field" />
37+
</composite-id>
38+
<bag name="RefferedDetails" lazy="true" inverse="true" generic="true">
39+
<key>
40+
<column name="id_Doc_detail" />
41+
<column name="id_base_detail" />
42+
</key>
43+
<one-to-many class="DocumentDetailDocument" />
44+
</bag>
45+
</class>
46+
</hibernate-mapping>

src/NHibernate/Loader/Collection/CollectionJoinWalker.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ protected SqlStringBuilder WhereString(string alias, string[] columnNames, SqlSt
2424
}
2525
else
2626
{
27-
string columnsJoin = string.Join(StringHelper.CommaSpace, StringHelper.Qualify(alias, columnNames));
27+
string columnsJoin =
28+
string.Join(StringHelper.CommaSpace, columnNames.ToArray(column => StringHelper.Qualify(GenerateAliasForColumn(alias, column), column)));
2829

2930
SqlStringBuilder buf = new SqlStringBuilder();
3031
if (columnNames.Length > 1)

src/NHibernate/Loader/JoinWalker.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,10 +1059,9 @@ protected SqlStringBuilder WhereString(string alias, string[] columnNames, int b
10591059
}
10601060
}
10611061

1062-
private static void ColumnFragment(SqlStringBuilder builder, string alias, string[] columnNames)
1062+
private void ColumnFragment(SqlStringBuilder builder, string alias, string[] columnNames)
10631063
{
10641064
//foo = ? and bar = ?
1065-
var prefix = alias + StringHelper.Dot;
10661065
var added = false;
10671066
foreach (var columnName in columnNames)
10681067
{
@@ -1072,8 +1071,7 @@ private static void ColumnFragment(SqlStringBuilder builder, string alias, strin
10721071
}
10731072

10741073
builder
1075-
.Add(prefix)
1076-
.Add(columnName)
1074+
.Add(StringHelper.Qualify(GenerateAliasForColumn(alias, columnName), columnName))
10771075
.Add("=")
10781076
.Add(Parameter.Placeholder);
10791077

0 commit comments

Comments
 (0)