Skip to content

Commit 9ae9555

Browse files
author
Patrick Flahan
committed
Added unit test for table per class discriminator using the insert attribute set to false
Modified AuditMetadataGenerator to check discriminator for insert flag and keep setting if false.
1 parent 559596a commit 9ae9555

File tree

6 files changed

+232
-0
lines changed

6 files changed

+232
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using NHibernate.Envers.Configuration.Attributes;
2+
3+
namespace NHibernate.Envers.Tests.Integration.Inheritance.TablePerClass.Discriminate
4+
{
5+
[Audited]
6+
public class BaseEntity
7+
{
8+
public virtual long Id { get; set; }
9+
public virtual ClassTypeEntity TypeId { get; set; }
10+
public virtual string Data { get; set; }
11+
12+
public override bool Equals(object obj)
13+
{
14+
var casted = obj as BaseEntity;
15+
if(casted==null)
16+
return false;
17+
18+
return Id == casted.Id
19+
&& TypeId.Id == casted.TypeId.Id
20+
&& string.Equals(Data, casted.Data);
21+
}
22+
23+
public override int GetHashCode()
24+
{
25+
return Id.GetHashCode();
26+
}
27+
}
28+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using NHibernate.Envers.Configuration.Attributes;
2+
3+
namespace NHibernate.Envers.Tests.Integration.Inheritance.TablePerClass.Discriminate
4+
{
5+
[Audited]
6+
public class ClassTypeEntity
7+
{
8+
public const string BaseName = "base";
9+
public const string SubtypeName = "subtype";
10+
11+
public virtual int Id { get; set; }
12+
public virtual string Type { get; set; }
13+
14+
public override bool Equals(object obj)
15+
{
16+
var casted = obj as ClassTypeEntity;
17+
if(casted==null)
18+
return false;
19+
return Id == casted.Id && Type == casted.Type;
20+
}
21+
22+
public override int GetHashCode()
23+
{
24+
return Id.GetHashCode();
25+
}
26+
}
27+
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Mapping;
4+
using NUnit.Framework;
5+
using SharpTestsEx;
6+
7+
namespace NHibernate.Envers.Tests.Integration.Inheritance.TablePerClass.Discriminate
8+
{
9+
/// <summary>
10+
/// Provides a basic set of tests to verify when the insert attribute of the discriminator element is set
11+
/// to false, that the setting will carry into the audit table settings.
12+
/// </summary>
13+
public class DiscriminatorTest : TestBase
14+
{
15+
private BaseEntity baseEntityVer1;
16+
private BaseEntity baseEntityVer2;
17+
private SubtypeEntity subtypeEntityVer1;
18+
private SubtypeEntity subtypeEntityVer2;
19+
20+
public DiscriminatorTest(AuditStrategyForTest strategyType) : base(strategyType)
21+
{
22+
}
23+
24+
/// <summary>
25+
/// Perform initialization for the test
26+
/// </summary>
27+
protected override void Initialize()
28+
{
29+
var baseEntityType = new ClassTypeEntity { Type = ClassTypeEntity.BaseName };
30+
var subtypeEntityType = new ClassTypeEntity { Type = ClassTypeEntity.SubtypeName };
31+
32+
//rev 1
33+
using (var tx = Session.BeginTransaction())
34+
{
35+
Session.Save(baseEntityType);
36+
Session.Save(subtypeEntityType);
37+
tx.Commit();
38+
}
39+
40+
//rev 2
41+
var baseEntity = new BaseEntity { TypeId = baseEntityType, Data = "parent data" };
42+
var subtypeEntity = new SubtypeEntity { TypeId = subtypeEntityType, Data = "child data", SubtypeData = "child specific data" };
43+
using (var tx = Session.BeginTransaction())
44+
{
45+
Session.Save(baseEntity);
46+
Session.Save(subtypeEntity);
47+
tx.Commit();
48+
}
49+
50+
//rev 3
51+
using (var tx = Session.BeginTransaction())
52+
{
53+
baseEntity.Data = "parent data modified";
54+
subtypeEntity.Data = "child data modified";
55+
tx.Commit();
56+
}
57+
58+
baseEntityVer1 = new BaseEntity { Id = baseEntity.Id, TypeId = baseEntityType, Data = "parent data" };
59+
subtypeEntityVer1 = new SubtypeEntity {Id = subtypeEntity.Id, TypeId = subtypeEntityType, Data = "child data", SubtypeData = "child specific data"};
60+
baseEntityVer2 = new BaseEntity {Id = baseEntity.Id, TypeId = baseEntityType, Data = "parent data modified"};
61+
subtypeEntityVer2 = new SubtypeEntity { Id = subtypeEntity.Id, TypeId = subtypeEntityType, Data = "child data modified", SubtypeData = "child specific data" };
62+
}
63+
64+
/// <summary>
65+
/// This test is here to verify that the NHibernate configuration was able to complete and that the set up
66+
/// performed in the Initialize method is correct.
67+
/// </summary>
68+
[Test]
69+
public void VerifyInitializeCompleted()
70+
{
71+
var classTypeEntityCount = Session.Query<ClassTypeEntity>().Count();
72+
Assert.IsTrue(classTypeEntityCount == 2, "Did not retrieve two ClassTypeEntity records, but received {0}", classTypeEntityCount);
73+
74+
var baseTypeCount = Session.Query<BaseEntity>()
75+
.Where(be => be.TypeId.Id == 1)
76+
.Count();
77+
Assert.IsTrue(baseTypeCount == 1, "Only expected one BaseEntity record, but received {0}", baseTypeCount);
78+
79+
var subtypeCount = Session.Query<SubtypeEntity>().Count();
80+
Assert.IsTrue(subtypeCount == 1, "Only expected one SubtypeEntity record, but received {0}", subtypeCount);
81+
}
82+
83+
/// <summary>
84+
/// Verify that revisions match for each type
85+
/// </summary>
86+
[Test]
87+
public void VerifyRevisionCounts()
88+
{
89+
CollectionAssert.AreEquivalent(new[] { 2, 3 },
90+
AuditReader().GetRevisions(typeof(BaseEntity), baseEntityVer1.Id));
91+
CollectionAssert.AreEquivalent(new[] { 2, 3 },
92+
AuditReader().GetRevisions(typeof(SubtypeEntity), subtypeEntityVer1.Id));
93+
}
94+
95+
[Test]
96+
public void VerifyHistoryOfParent()
97+
{
98+
AuditReader().Find<BaseEntity>(baseEntityVer1.Id, 2)
99+
.Should().Be.EqualTo(baseEntityVer1);
100+
101+
AuditReader().Find<BaseEntity>(baseEntityVer2.Id, 3)
102+
.Should().Be.EqualTo(baseEntityVer2);
103+
}
104+
105+
[Test]
106+
public void VerifyHistoryOfChild()
107+
{
108+
AuditReader().Find<SubtypeEntity>(subtypeEntityVer1.Id, 2)
109+
.Should().Be.EqualTo(subtypeEntityVer1);
110+
111+
AuditReader().Find<SubtypeEntity>(subtypeEntityVer2.Id, 3)
112+
.Should().Be.EqualTo(subtypeEntityVer2);
113+
}
114+
}
115+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
3+
assembly="NHibernate.Envers.Tests"
4+
namespace="NHibernate.Envers.Tests.Integration.Inheritance.TablePerClass.Discriminate">
5+
6+
<class name="ClassTypeEntity">
7+
<id name="Id">
8+
<generator class="native"/>
9+
</id>
10+
<property name="Type"/>
11+
</class>
12+
13+
<class name="BaseEntity" discriminator-value="1">
14+
<id name="Id">
15+
<generator class="native"/>
16+
</id>
17+
18+
<discriminator type="Int32" insert="false">
19+
<column name="TypeId" not-null="true" sql-type="int" />
20+
</discriminator>
21+
22+
<property name="Data"/>
23+
<many-to-one name="TypeId" column="TypeId" class="ClassTypeEntity" />
24+
</class>
25+
26+
<subclass name="SubtypeEntity" extends="BaseEntity" discriminator-value="2">
27+
<property name="SubtypeData" />
28+
</subclass>
29+
30+
31+
</hibernate-mapping>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using NHibernate.Envers.Configuration.Attributes;
2+
3+
namespace NHibernate.Envers.Tests.Integration.Inheritance.TablePerClass.Discriminate
4+
{
5+
[Audited]
6+
public class SubtypeEntity : BaseEntity
7+
{
8+
public virtual string SubtypeData { get; set; }
9+
10+
public override bool Equals(object obj)
11+
{
12+
var casted = obj as SubtypeEntity;
13+
if (casted == null)
14+
return false;
15+
16+
return base.Equals(casted)
17+
&& string.Equals(SubtypeData, casted.SubtypeData);
18+
}
19+
20+
public override int GetHashCode()
21+
{
22+
return base.GetHashCode();
23+
}
24+
}
25+
}

Src/NHibernate.Envers/Configuration/Metadata/AuditMetadataGenerator.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,12 @@ private Tuple<XElement, IExtendedPropertyMapper, string> generateMappingData(
332332
// Database column or SQL formula allowed to distinguish entity types
333333
MetadataTools.AddColumnsOrFormulas(discriminatorElement, pc.Discriminator.ColumnIterator);
334334
discriminatorElement.Add(new XAttribute("type", pc.Discriminator.Type.Name));
335+
336+
// check if the origin discriminator is not insertable and maintain setting for audit class
337+
if (!pc.IsDiscriminatorInsertable)
338+
{
339+
discriminatorElement.Add(new XAttribute("insert", "false"));
340+
}
335341
}
336342

337343
// Adding the "revision type" property

0 commit comments

Comments
 (0)