1
1
package com .fasterxml .jackson .datatype .hibernate4 ;
2
2
3
3
import java .io .IOException ;
4
+ import java .lang .reflect .Field ;
5
+ import java .lang .reflect .Method ;
4
6
import java .util .HashMap ;
5
7
6
8
import com .fasterxml .jackson .core .*;
18
20
import org .hibernate .engine .spi .SessionImplementor ;
19
21
import org .hibernate .proxy .HibernateProxy ;
20
22
import org .hibernate .proxy .LazyInitializer ;
23
+ import org .hibernate .proxy .pojo .BasicLazyInitializer ;
21
24
22
25
/**
23
26
* Serializer to use for values proxied using {@link org.hibernate.proxy.HibernateProxy}.
@@ -174,15 +177,18 @@ protected Object findProxied(HibernateProxy proxy)
174
177
LazyInitializer init = proxy .getHibernateLazyInitializer ();
175
178
if (!_forceLazyLoading && init .isUninitialized ()) {
176
179
if (_serializeIdentifier ) {
177
- final String idName ;
180
+ String idName ;
178
181
if (_mapping != null ) {
179
182
idName = _mapping .getIdentifierPropertyName (init .getEntityName ());
180
183
} else {
181
184
final SessionImplementor session = init .getSession ();
182
185
if (session != null ) {
183
186
idName = session .getFactory ().getIdentifierPropertyName (init .getEntityName ());
184
187
} else {
185
- idName = init .getEntityName ();
188
+ idName = ProxyReader .getIdentifierPropertyName (init );
189
+ if (idName == null ) {
190
+ idName = init .getEntityName ();
191
+ }
186
192
}
187
193
}
188
194
final Object idValue = init .getIdentifier ();
@@ -194,4 +200,40 @@ protected Object findProxied(HibernateProxy proxy)
194
200
}
195
201
return init .getImplementation ();
196
202
}
203
+
204
+ // Alas, hibernate offers no public api to access this information, so we must resort to ugly hacks ...
205
+ protected static class ProxyReader {
206
+
207
+ // static final so the JVM can inline the lookup
208
+ private static final Field getIdentifierMethod ;
209
+
210
+ static {
211
+ try {
212
+ getIdentifierMethod = BasicLazyInitializer .class .getDeclaredField ("getIdentifierMethod" );
213
+ getIdentifierMethod .setAccessible (true );
214
+ } catch (Exception e ) {
215
+ // should never happen: the field exists in all versions of hibernate 4 and 5
216
+ throw new RuntimeException (e );
217
+ }
218
+ }
219
+
220
+ /**
221
+ * @return the name of the identifier property, or null if the name could not be determined
222
+ */
223
+ static String getIdentifierPropertyName (LazyInitializer init ) {
224
+ try {
225
+ Method idGetter = (Method ) getIdentifierMethod .get (init );
226
+ if (idGetter == null ) {
227
+ return null ;
228
+ }
229
+ String name = idGetter .getName ();
230
+ if (name .startsWith ("get" )) {
231
+ name = Character .toLowerCase (name .charAt (3 )) + name .substring (4 );
232
+ }
233
+ return name ;
234
+ } catch (Exception e ) {
235
+ throw new RuntimeException (e );
236
+ }
237
+ }
238
+ }
197
239
}
0 commit comments