1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using System . Diagnostics ;
4
+ using NHibernate . Cfg . XmlHbmBinding ;
3
5
using NHibernate . Engine ;
6
+ using NHibernate . Mapping ;
4
7
using NHibernate . SqlCommand ;
5
8
using NHibernate . Type ;
6
9
using NHibernate . Util ;
@@ -12,6 +15,7 @@ namespace NHibernate.Persister.Entity
12
15
/// </summary>
13
16
public abstract class AbstractPropertyMapping : IPropertyMapping
14
17
{
18
+ private readonly HashSet < string > duplicateIncompatiblePaths = new HashSet < string > ( ) ;
15
19
private readonly Dictionary < string , IType > typesByPropertyPath = new Dictionary < string , IType > ( ) ;
16
20
private readonly Dictionary < string , string [ ] > columnsByPropertyPath = new Dictionary < string , string [ ] > ( ) ;
17
21
private readonly Dictionary < string , string [ ] > formulaTemplatesByPropertyPath = new Dictionary < string , string [ ] > ( ) ;
@@ -91,20 +95,133 @@ public virtual string[] ToColumns(string propertyName)
91
95
92
96
#endregion
93
97
98
+ [ Obsolete ]
94
99
protected void AddPropertyPath ( string path , IType type , string [ ] columns , string [ ] formulaTemplates )
95
100
{
96
- if ( ! typesByPropertyPath . ContainsKey ( path ) )
101
+ AddPropertyPath ( path , type , columns , formulaTemplates , null ) ;
102
+ }
103
+
104
+ protected void AddPropertyPath (
105
+ string path ,
106
+ IType type ,
107
+ string [ ] columns ,
108
+ string [ ] formulaTemplates ,
109
+ IMapping factory )
110
+ {
111
+ if ( typesByPropertyPath . TryGetValue ( path , out var existingType ) || duplicateIncompatiblePaths . Contains ( path ) )
112
+ {
113
+ // If types match or the new type is not an association type, there is nothing for us to do
114
+ if ( type == existingType || existingType == null || ! ( type is IAssociationType ) )
115
+ {
116
+ //TODO: Log duplicated
117
+ }
118
+ else if ( ! ( existingType is IAssociationType ) )
119
+ {
120
+ // Workaround for org.hibernate.cfg.annotations.PropertyBinder.bind() adding a component for *ToOne ids
121
+ //TODO: Log duplicated
122
+ }
123
+ else
124
+ {
125
+ if ( type is AnyType && existingType is AnyType )
126
+ {
127
+ // TODO: not sure how to handle any types. For now we just return and let the first type dictate what type the property has...
128
+ }
129
+ else
130
+ {
131
+ IType commonType = null ;
132
+ if ( type is CollectionType typeCollection && existingType is CollectionType existingCollection )
133
+ {
134
+ var metadata = ( IMetadata ) factory ;
135
+ var thisCollection = metadata . GetCollection ( existingCollection . Role ) ;
136
+ var otherCollection = metadata . GetCollection ( typeCollection . Role ) ;
137
+
138
+ if ( thisCollection . Equals ( otherCollection ) )
139
+ {
140
+ //TODO: Log duplicated
141
+ }
142
+ else
143
+ {
144
+ //TODO: log Incompatible Registration
145
+ }
146
+ }
147
+ else if ( type is EntityType entityType1 && existingType is EntityType entityType2 )
148
+ {
149
+ if ( entityType1 . GetAssociatedEntityName ( ) == entityType2 . GetAssociatedEntityName ( ) )
150
+ {
151
+ //TODO: Log duplicated
152
+ return ;
153
+ }
154
+
155
+ commonType = GetCommonType ( ( IMetadata ) factory , entityType1 , entityType2 ) ;
156
+ }
157
+ else
158
+ {
159
+ //TODO: log Incompatible Registration
160
+ }
161
+
162
+ if ( commonType == null )
163
+ {
164
+ duplicateIncompatiblePaths . Add ( path ) ;
165
+ typesByPropertyPath . Remove ( path ) ;
166
+ columnsByPropertyPath [ path ] = columns ;
167
+
168
+ if ( formulaTemplates != null )
169
+ {
170
+ formulaTemplatesByPropertyPath [ path ] = formulaTemplates ;
171
+ }
172
+ }
173
+ else
174
+ {
175
+ typesByPropertyPath [ path ] = commonType ;
176
+ }
177
+ }
178
+ }
179
+ }
180
+ else
97
181
{
98
182
typesByPropertyPath [ path ] = type ;
99
183
columnsByPropertyPath [ path ] = columns ;
100
-
184
+
101
185
if ( formulaTemplates != null )
102
186
{
103
187
formulaTemplatesByPropertyPath [ path ] = formulaTemplates ;
104
188
}
105
189
}
106
190
}
107
191
192
+ private static IType GetCommonType ( IMetadata metadata , EntityType entityType1 , EntityType entityType2 )
193
+ {
194
+ var thisClass = metadata . GetPersistentClass ( entityType1 . GetAssociatedEntityName ( ) ) ;
195
+ var otherClass = metadata . GetPersistentClass ( entityType2 . GetAssociatedEntityName ( ) ) ;
196
+ var commonClass = GetCommonPersistent ( thisClass , otherClass ) ;
197
+
198
+ if ( commonClass == null )
199
+ {
200
+ return null ;
201
+ }
202
+
203
+ switch ( entityType1 )
204
+ {
205
+ case ManyToOneType many :
206
+ return new ManyToOneType ( many , commonClass . EntityName ) ;
207
+ case SpecialOneToOneType special :
208
+ return new SpecialOneToOneType ( special , commonClass . EntityName ) ;
209
+ default :
210
+ throw new Exception ( "Unexpected entity type: " + entityType1 ) ;
211
+
212
+ }
213
+ }
214
+
215
+ private static PersistentClass GetCommonPersistent ( PersistentClass class1 , PersistentClass class2 )
216
+ {
217
+ while ( class2 != null && class2 . MappedClass != null && ! class2 . MappedClass . IsAssignableFrom ( class1 . MappedClass ) )
218
+ {
219
+ class2 = class2 . Superclass ;
220
+ }
221
+
222
+ return class2 ;
223
+ }
224
+
108
225
protected internal void InitPropertyPaths ( string path , IType type , string [ ] columns , string [ ] formulaTemplates , IMapping factory )
109
226
{
110
227
if ( columns . Length != type . GetOwnerColumnSpan ( factory ) )
@@ -136,7 +253,7 @@ protected internal void InitPropertyPaths( string path, IType type, string[] col
136
253
137
254
if ( path != null )
138
255
{
139
- AddPropertyPath ( path , type , columns , formulaTemplates ) ;
256
+ AddPropertyPath ( path , type , columns , formulaTemplates , factory ) ;
140
257
}
141
258
142
259
if ( type . IsComponentType )
@@ -165,15 +282,15 @@ protected void InitIdentifierPropertyPaths(string path, EntityType etype, string
165
282
if ( ! hasNonIdentifierPropertyNamedId )
166
283
{
167
284
string idpath1 = ExtendPath ( path , EntityPersister . EntityID ) ;
168
- AddPropertyPath ( idpath1 , idtype , columns , null ) ;
285
+ AddPropertyPath ( idpath1 , idtype , columns , null , factory ) ;
169
286
InitPropertyPaths ( idpath1 , idtype , columns , null , factory ) ;
170
287
}
171
288
}
172
289
173
290
if ( idPropName != null )
174
291
{
175
292
string idpath2 = ExtendPath ( path , idPropName ) ;
176
- AddPropertyPath ( idpath2 , idtype , columns , null ) ;
293
+ AddPropertyPath ( idpath2 , idtype , columns , null , factory ) ;
177
294
InitPropertyPaths ( idpath2 , idtype , columns , null , factory ) ;
178
295
}
179
296
}
0 commit comments