View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2009 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.services.remoting.jaxb.hibernate;
18  
19  import java.lang.reflect.Method;
20  
21  import org.slf4j.Logger;
22  import org.slf4j.LoggerFactory;
23  
24  import com.sun.xml.bind.api.AccessorException;
25  import com.sun.xml.bind.v2.runtime.JAXBContextImpl;
26  import com.sun.xml.bind.v2.runtime.reflect.Accessor;
27  
28  /**
29   * A JAXB Accessor that replaces uninitialized values by <code>null</code> to avoid LazyInitializationException.
30   *
31   * @svnLink $Revision: 3945 $;$Date: 2009-10-16 09:31:52 +0200 (Fr, 16. Okt 2009) $;$Author: swismer $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/remoting_jaxws/src/main/java/ch/elca/el4j/services/remoting/jaxb/hibernate/HibernateJAXBAccessor.java $
32   * 
33   * @param <B> the bean type
34   * @param <V> the value type
35   *
36   * @author clemenb (see https://forum.hibernate.org/viewtopic.php?f=1&t=998896)
37   */
38  public class HibernateJAXBAccessor<B, V> extends Accessor<B, V> {
39  
40  	/**
41  	 * The delegate accessor.
42  	 */
43  	private Accessor<B, V> delegate;
44  	
45  	/**
46  	 * The method to call for checking if value is uninitialized.
47  	 */
48  	private final Method hibernateInitializationCheck;
49  
50  	/**
51  	 * @param delegate                        the delegate accessor
52  	 * @param hibernateInitializationCheck    the method to call for checking if value is uninitialized
53  	 */
54  	protected HibernateJAXBAccessor(Accessor<B, V> delegate, Method hibernateInitializationCheck) {
55  		super(delegate.getValueType());
56  		if (delegate == null) {
57  			throw new IllegalArgumentException("delegate must not be null");
58  		} else if (hibernateInitializationCheck == null) {
59  			throw new IllegalArgumentException("hibernateInitializationCheck must not be null");
60  		}
61  
62  		this.delegate = delegate;
63  		this.hibernateInitializationCheck = hibernateInitializationCheck;
64  	}
65  
66  	@Override
67  	public Accessor<B, V> optimize(JAXBContextImpl context) {
68  		delegate = delegate.optimize(context);
69  		return this;
70  	}
71  
72  	@Override
73  	public V get(B bean) throws AccessorException {
74  		return hideLazy(delegate.get(bean));
75  	}
76  
77  	@Override
78  	public void set(B bean, V value) throws AccessorException {
79  		delegate.set(bean, value);
80  	}
81  
82  	/**
83  	 * @param value    the value to check
84  	 * @return         the value if it is initialized, otherwise <code>null</code> 
85  	 */
86  	protected V hideLazy(V value) {
87  		try {
88  			boolean isInitialized = (Boolean) hibernateInitializationCheck.invoke(null, new Object[] {value});
89  			if (isInitialized) {
90  				return value;
91  			} else {
92  				return null;
93  			}
94  		} catch (Exception e) {
95  			Logger logger = LoggerFactory.getLogger(HibernateJAXBAccessor.class);
96  			logger.error("Failed to determine state of Hibernate object or collection, assuming " + value
97  				+ " is initialized", e);
98  			return null;
99  		}
100 	}
101 }