Project

General

Profile

« Previous | Next » 

Revision 2a2a9f1c

Added by Andreas Müller over 8 years ago

Fix AdvancedBeanInitializer for envers collections/maps #5077

View differences:

cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/initializer/AdvancedBeanInitializer.java
25 25
import org.hibernate.Query;
26 26
import org.hibernate.collection.internal.AbstractPersistentCollection;
27 27
import org.hibernate.collection.internal.PersistentMap;
28
import org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy;
29
import org.hibernate.envers.entities.mapper.relation.lazy.proxy.MapProxy;
30
import org.hibernate.envers.entities.mapper.relation.lazy.proxy.SortedMapProxy;
28 31
import org.hibernate.proxy.HibernateProxy;
29 32
import org.springframework.beans.factory.annotation.Autowired;
30 33

  
......
198 201
    }
199 202

  
200 203

  
201

  
202
    // propPath contains either a single field or a nested path
204
   // propPath contains either a single field or a nested path
203 205
    // split next path token off and keep the remaining as nestedPath
204 206
    private void initializeNodeNoWildcard(BeanInitNode node) {
205 207

  
......
226 228
            }
227 229
            //new
228 230
            for (Object parentBean : parentBeans){
229
                String propertyName = mapFieldToPropertyName(property, parentBean.getClass().getSimpleName());
230
                try{
231
                    Object propertyValue = PropertyUtils.getProperty(parentBean, propertyName);
232
                    preparePropertyValueForBulkLoadOrStore(node, parentBean, property, propertyValue);
233
                } catch (IllegalAccessException e) {
234
                    String message = "Illegal access on property " + property;
235
                    logger.error(message);
236
                    throw new RuntimeException(message, e);
237
                } catch (InvocationTargetException e) {
238
                    String message = "Cannot invoke property " + property + " not found";
239
                    logger.error(message);
240
                    throw new RuntimeException(message, e);
241
                } catch (NoSuchMethodException e) {
242
                    String message = "Property " + propertyName + " not found for class " + parentClazz;
243
                    logger.error(message);
244
                    throw new RuntimeException(message, e);
245
                }
246
            }
247

  
231
                preparePropertyForSingleBean(node, property, parentClazz, parentBean);
232
            }//end for
248 233
            //end new
249

  
250 234
//			 initializeNodeNoWildcardOld(node, property, index, parentBeans);  //move bulkLoadLazies up again, if uncomment this line
251
        }
235
        } //end for
252 236
        bulkLoadLazies(node);
253

  
254 237
    }
255 238

  
256 239
    /**
257
     * @param node
258
     * @param property
259
     * @param index
260
     * @param parentBeans
261
     * @throws IllegalAccessException
262
     * @throws InvocationTargetException
263
     * @throws NoSuchMethodException
240
     * Prepare a single property of a non-collection bean. Collections are handled elsewhere.
264 241
     */
265
    private void initializeNodeNoWildcardOld(BeanInitNode node,
266
            String property, Integer index, Set<Object> parentBeans)
267
            throws IllegalAccessException, InvocationTargetException,
268
            NoSuchMethodException {
269
        for (Object bean : parentBeans){
270

  
271
            PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, property);
272
            if (logger.isTraceEnabled()){logger.trace("   unwrap " + node.toStringNoWildcard() + " ... ");}
273
            // [1] initialize the bean named by property
274
            Object unwrappedPropertyBean = invokeInitialization(bean, propertyDescriptor);
275
            if (logger.isTraceEnabled()){logger.trace("   unwrap " + node.toStringNoWildcard() + " - DONE ");}
276

  
277

  
278
            // [2]
279
            // handle property
280
            if(unwrappedPropertyBean != null ){
281
                initializeNodeSinglePropertyOld(node, property, index, bean, unwrappedPropertyBean);
282
            }
242
    private void preparePropertyForSingleBean(BeanInitNode node, String property, Class<?> parentClazz, Object bean) {
243
        String propertyName = mapFieldToPropertyName(property, bean.getClass().getSimpleName());
244
        try{
245
            Object propertyValue = PropertyUtils.getProperty(bean, propertyName);
246
            preparePropertyValueForBulkLoadOrStore(node, bean, property, propertyValue);
247
        } catch (IllegalAccessException e) {
248
            String message = "Illegal access on property " + property;
249
            logger.error(message);
250
            throw new RuntimeException(message, e);
251
        } catch (InvocationTargetException e) {
252
            String message = "Cannot invoke property " + property + " not found";
253
            logger.error(message);
254
            throw new RuntimeException(message, e);
255
        } catch (NoSuchMethodException e) {
256
            String message = "Property " + propertyName + " not found for class " + parentClazz;
257
            logger.error(message);
258
            throw new RuntimeException(message, e);
283 259
        }
284 260
    }
285 261

  
262
//    /**
263
//     * @param node
264
//     * @param property
265
//     * @param index
266
//     * @param parentBeans
267
//     * @throws IllegalAccessException
268
//     * @throws InvocationTargetException
269
//     * @throws NoSuchMethodException
270
//     */
271
//    private void initializeNodeNoWildcardOld(BeanInitNode node,
272
//                String property,
273
//                Integer index,
274
//                Set<Object> parentBeans)
275
//            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
276
//    {
277
//        for (Object bean : parentBeans){
278
//
279
//            PropertyDescriptor propertyDescriptor = PropertyUtils.getPropertyDescriptor(bean, property);
280
//            if (logger.isTraceEnabled()){logger.trace("   unwrap " + node.toStringNoWildcard() + " ... ");}
281
//            // [1] initialize the bean named by property
282
//            Object unwrappedPropertyBean = invokeInitialization(bean, propertyDescriptor);
283
//            if (logger.isTraceEnabled()){logger.trace("   unwrap " + node.toStringNoWildcard() + " - DONE ");}
284
//
285
//
286
//            // [2]
287
//            // handle property
288
//            if(unwrappedPropertyBean != null ){
289
//                initializeNodeSinglePropertyOld(node, property, index, bean, unwrappedPropertyBean);
290
//            }
291
//        }
292
//    }
293

  
286 294
    /**
287 295
     * @param node
288 296
     * @param propertyValue
289 297
     * @param parentBean
290 298
     * @param param
291 299
     */
292
    private void preparePropertyValueForBulkLoadOrStore(BeanInitNode node, Object parentBean, String param, Object propertyValue) {
300
    private void preparePropertyValueForBulkLoadOrStore(BeanInitNode node,
301
            Object parentBean,
302
            String param,
303
            Object propertyValue)
304
    {
293 305
        BeanInitNode sibling = node.getSibling(param);
294 306

  
295 307
        if (propertyValue instanceof AbstractPersistentCollection ){
......
308 320
                    }
309 321
                }
310 322
            }
323
        } else if (propertyValue instanceof CollectionProxy
324
                || propertyValue instanceof MapProxy<?, ?>
325
                || propertyValue instanceof SortedMapProxy<?, ?>){
326
            //hibernate envers collections
327
            //TODO check if other code works with audited data at all as we use HQL queries
328
            if (!node.hasWildcardToManySibling()){  //if wildcard sibling exists the lazies are already prepared there
329
                Collection<?> collection = (Collection<?>)propertyValue;
330
                //TODO it is difficult to find out if an envers collection is initiallized
331
                //but possiblie via reflection. If the "delegate" parameter is null it is not yet initialized.
332
                //However, as we do not know if envers initialization works at all together with the AdvancedBeanInitializer
333
                //we initialize each collection immediately here by calling size()
334
                collection.size();  //initialize
335
                storeInitializedEnversCollection(collection, node, param);
336
            }
311 337
        }else{
312 338
            //singles
313 339
            if (!node.hasWildcardToOneSibling()){  //if wildcard exists the lazies are already prepared there
......
349 375

  
350 376
	private void storeInitializedCollection(AbstractPersistentCollection persistedCollection,
351 377
			BeanInitNode node, String param) {
352
		Collection<?> collection;
353 378

  
379
	    Collection<?> collection;
354 380
		if (persistedCollection  instanceof Collection) {
355 381
			collection = (Collection<?>) persistedCollection;
356 382
		}else if (persistedCollection instanceof Map) {
......
363 389
		}
364 390
	}
365 391

  
392
	/**
393
	 * @see #storeInitializedCollection(AbstractPersistentCollection, BeanInitNode, String)alizedCollection
394
	 */
395
	private void storeInitializedEnversCollection(Collection<?> enversCollection,
396
            BeanInitNode node, String param) {
397
	    if (enversCollection instanceof CollectionProxy
398
                || enversCollection instanceof MapProxy<?, ?>
399
                || enversCollection instanceof SortedMapProxy<?, ?>){
400
	        Collection<?> collection;
401
	        if (enversCollection instanceof MapProxy
402
	                || enversCollection instanceof SortedMapProxy<?, ?>) {
403
	            collection = ((Map<?,?>)enversCollection).values();
404
	        }else if (enversCollection instanceof CollectionProxy) {
405
	            collection = enversCollection;
406
	        }else{
407
	            throw new RuntimeException ("Non MapProxy and non CollectionProxy case not handled in storeInitializedEnversCollection()");
408
	        }
409
	        for (Object value : collection){
410
	            preparePropertyValueForBulkLoadOrStore(node, null, param, value);
411
	        }
412
	    }
413
    }
414

  
415

  
366 416
	private void bulkLoadLazies(BeanInitNode node) {
367 417

  
368 418
		if (logger.isTraceEnabled()){logger.trace("bulk load " +  node);}

Also available in: Unified diff