001: package org.hibernate.proxy;
002:
003: import java.io.Serializable;
004:
005: import org.hibernate.HibernateException;
006: import org.hibernate.LazyInitializationException;
007: import org.hibernate.ObjectNotFoundException;
008: import org.hibernate.engine.EntityKey;
009: import org.hibernate.engine.SessionImplementor;
010:
011: /**
012: * Convenience base class for lazy initialization handlers. Centralizes the
013: * basic plumbing of doing lazy initialization freeing subclasses to
014: * acts as essentially adapters to their intended entity mode and/or
015: * proxy generation strategy.
016: *
017: * @author Gavin King
018: */
019: public abstract class AbstractLazyInitializer implements
020: LazyInitializer {
021:
022: private Object target;
023: private boolean initialized;
024: private String entityName;
025: private Serializable id;
026: private transient SessionImplementor session;
027: private boolean unwrap;
028:
029: protected AbstractLazyInitializer(String entityName,
030: Serializable id, SessionImplementor session) {
031: this .id = id;
032: this .session = session;
033: this .entityName = entityName;
034: }
035:
036: public final Serializable getIdentifier() {
037: return id;
038: }
039:
040: public final void setIdentifier(Serializable id) {
041: this .id = id;
042: }
043:
044: public final String getEntityName() {
045: return entityName;
046: }
047:
048: public final boolean isUninitialized() {
049: return !initialized;
050: }
051:
052: public final SessionImplementor getSession() {
053: return session;
054: }
055:
056: public final void initialize() throws HibernateException {
057: if (!initialized) {
058: if (session == null) {
059: throw new LazyInitializationException(
060: "could not initialize proxy - no Session");
061: } else if (!session.isOpen()) {
062: throw new LazyInitializationException(
063: "could not initialize proxy - the owning Session was closed");
064: } else if (!session.isConnected()) {
065: throw new LazyInitializationException(
066: "could not initialize proxy - the owning Session is disconnected");
067: } else {
068: target = session.immediateLoad(entityName, id);
069: initialized = true;
070: checkTargetState();
071: }
072: } else {
073: checkTargetState();
074: }
075: }
076:
077: private void checkTargetState() {
078: if (!unwrap) {
079: if (target == null) {
080: getSession().getFactory().getEntityNotFoundDelegate()
081: .handleEntityNotFound(entityName, id);
082: }
083: }
084: }
085:
086: public final void setSession(SessionImplementor s)
087: throws HibernateException {
088: if (s != session) {
089: if (isConnectedToSession()) {
090: //TODO: perhaps this should be some other RuntimeException...
091: throw new HibernateException(
092: "illegally attempted to associate a proxy with two open Sessions");
093: } else {
094: session = s;
095: }
096: }
097: }
098:
099: protected final boolean isConnectedToSession() {
100: return session != null && session.isOpen()
101: && session.getPersistenceContext().containsProxy(this );
102: }
103:
104: public final void setImplementation(Object target) {
105: this .target = target;
106: initialized = true;
107: }
108:
109: /**
110: * Return the underlying persistent object, initializing if necessary
111: */
112: public final Object getImplementation() {
113: initialize();
114: return target;
115: }
116:
117: /**
118: * Return the underlying persistent object in the given <tt>Session</tt>, or null,
119: * do not initialize the proxy
120: */
121: public final Object getImplementation(SessionImplementor s)
122: throws HibernateException {
123: final EntityKey entityKey = new EntityKey(getIdentifier(), s
124: .getFactory().getEntityPersister(getEntityName()), s
125: .getEntityMode());
126: return s.getPersistenceContext().getEntity(entityKey);
127: }
128:
129: protected final Object getTarget() {
130: return target;
131: }
132:
133: public boolean isUnwrap() {
134: return unwrap;
135: }
136:
137: public void setUnwrap(boolean unwrap) {
138: this.unwrap = unwrap;
139: }
140:
141: }
|