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 }