Skip to content

Commit 0d8a26d

Browse files
author
Misha Urubkov
committed
#1496 Fix ManyToOneType.IsModified to handle both object instance and identifier passed to the parameter “old”.
The tests "EventListener_Entity_ChangeProperty" and "EventListener_EntityWithCompositeId_ChangeProperty" fail for current code in ManyToOneType.IsModified(…) where "old" parameter is not parsed. The tests "SelectBeforeUpdate_EntityWithCompositeId_ChangeProperty" and "SelectBeforeUpdate_ManyToOneWithCompositeId_ChangeProperty" fail if we apply Hibernate fix HHH-3730 "(var oldIdentifier =GetIdentifier(old, session))" All tests pass if we apply proposed fix: "var oldIdentifier = IsIdentifier(old, session) ? old : GetIdentifier(old, session);" I added extra tests to see what data hit the ManyToOneType.IsModified(…). We can leave just 4 tests listed above and remove or set to [Ignore] others. ManyToOneType.IsModifiedAsync(...) could be fixed same way but would like to hear the feedback on the issue and proposed solution first.
1 parent c020a40 commit 0d8a26d

File tree

5 files changed

+688
-1
lines changed

5 files changed

+688
-1
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using NHibernate.Event;
6+
7+
namespace NHibernate.Test.NHSpecificTest.GH1496
8+
{
9+
public class AuditEventListener : IPostUpdateEventListener
10+
{
11+
public IList<Item> ModifiedItems { get; set; } = new List<Item>();
12+
private bool isActive = false;
13+
14+
public void Start()
15+
{
16+
ModifiedItems.Clear();
17+
isActive = true;
18+
}
19+
20+
public void Stop()
21+
{
22+
isActive = false;
23+
}
24+
25+
public Task OnPostUpdateAsync(PostUpdateEvent @event, CancellationToken cancellationToken)
26+
{
27+
throw new NotImplementedException();
28+
}
29+
30+
public void OnPostUpdate(PostUpdateEvent @event)
31+
{
32+
if (isActive == false)
33+
{ return; }
34+
35+
var modifiedItems = @event.Persister.FindModified(@event.OldState, @event.State, @event.Entity, @event.Session);
36+
foreach (int index in modifiedItems)
37+
{
38+
ModifiedItems.Add(new Item
39+
{
40+
Index = index,
41+
OldState = @event.OldState[index],
42+
State = @event.State[index]
43+
});
44+
}
45+
}
46+
47+
public class Item
48+
{
49+
public int Index { get; set; }
50+
public object OldState { get; set; }
51+
public object State { get; set; }
52+
}
53+
54+
}
55+
56+
57+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using System;
2+
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH1496
5+
{
6+
// Entity with ManyToOne type (Address) with regular (int) Id
7+
public class Person
8+
{
9+
public virtual int Id { get; set; }
10+
11+
public virtual string Name { get; set; }
12+
13+
public virtual Address Address { get; set; }
14+
15+
public Person()
16+
{
17+
}
18+
19+
public Person(int id, string name, Address address)
20+
{
21+
Id = id;
22+
Name = name;
23+
Address = address;
24+
}
25+
}
26+
27+
// Entity with ManyToOne type (Contact) with comnposite (ContactId) Id.
28+
public class Employee
29+
{
30+
public virtual int Id { get; set; }
31+
32+
public virtual string Name { get; set; }
33+
34+
public virtual Contact Contact { get; set; }
35+
36+
public Employee()
37+
{
38+
}
39+
40+
public Employee(int id, string name)
41+
{
42+
Id = id;
43+
Name = name;
44+
}
45+
}
46+
47+
48+
public class Address
49+
{
50+
public virtual int Id { get; set; }
51+
public virtual string PostalCode { get; set; }
52+
53+
public virtual string State { get; set; }
54+
55+
public virtual string Street { get; set; }
56+
57+
public Address()
58+
{ }
59+
60+
public Address(string postalCode, string state, string street)
61+
{
62+
PostalCode = postalCode;
63+
State = state;
64+
Street = street;
65+
}
66+
}
67+
68+
69+
[Serializable]
70+
public class Contact
71+
{
72+
public virtual ContactIdentifier ContactIdentifier { get; set; }
73+
public virtual string Phone { get; set; }
74+
}
75+
76+
77+
public class ContactIdentifier : IEquatable<ContactIdentifier>
78+
{
79+
public virtual string TypeName { get; set; }
80+
public virtual string ContactId { get; set; }
81+
82+
public ContactIdentifier(string typeName, string contactId)
83+
{
84+
ContactId = contactId;
85+
TypeName = typeName;
86+
}
87+
88+
public ContactIdentifier() { }
89+
90+
public virtual bool Equals(ContactIdentifier other)
91+
{
92+
if (ReferenceEquals(null, other)) return false;
93+
if (ReferenceEquals(this, other)) return true;
94+
return string.Equals(TypeName, other.TypeName) && string.Equals(ContactId, other.ContactId);
95+
}
96+
97+
public override bool Equals(object obj)
98+
{
99+
if (ReferenceEquals(null, obj)) return false;
100+
if (ReferenceEquals(this, obj)) return true;
101+
if (obj.GetType() != this.GetType()) return false;
102+
return Equals((ContactIdentifier) obj);
103+
}
104+
105+
public override int GetHashCode()
106+
{
107+
unchecked
108+
{
109+
return ((TypeName != null ? TypeName.GetHashCode() : 0) * 397) ^ (ContactId != null ? ContactId.GetHashCode() : 0);
110+
}
111+
}
112+
113+
public static bool operator ==(ContactIdentifier left, ContactIdentifier right)
114+
{
115+
return Equals(left, right);
116+
}
117+
118+
public static bool operator !=(ContactIdentifier left, ContactIdentifier right)
119+
{
120+
return !Equals(left, right);
121+
}
122+
123+
124+
125+
}
126+
127+
128+
129+
}

0 commit comments

Comments
 (0)