| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.openjpa.persistence; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.Externalizable; |
| import java.io.IOException; |
| import java.io.ObjectInput; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutput; |
| import java.io.ObjectOutputStream; |
| import java.io.ObjectStreamClass; |
| import java.lang.reflect.Array; |
| import java.lang.reflect.Field; |
| import java.lang.reflect.Method; |
| import java.sql.Connection; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.EnumSet; |
| import java.util.HashMap; |
| import java.util.IdentityHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.persistence.CacheRetrieveMode; |
| import javax.persistence.CacheStoreMode; |
| import javax.persistence.EntityGraph; |
| import javax.persistence.EntityManager; |
| import javax.persistence.FlushModeType; |
| import javax.persistence.LockModeType; |
| import javax.persistence.PessimisticLockScope; |
| import javax.persistence.Query; |
| import javax.persistence.StoredProcedureQuery; |
| import javax.persistence.Tuple; |
| import javax.persistence.TypedQuery; |
| import javax.persistence.criteria.CriteriaDelete; |
| import javax.persistence.criteria.CriteriaQuery; |
| import javax.persistence.criteria.CriteriaUpdate; |
| import javax.persistence.criteria.ParameterExpression; |
| import javax.persistence.metamodel.Metamodel; |
| |
| import org.apache.openjpa.conf.Compatibility; |
| import org.apache.openjpa.conf.OpenJPAConfiguration; |
| import org.apache.openjpa.ee.ManagedRuntime; |
| import org.apache.openjpa.enhance.PCEnhancer; |
| import org.apache.openjpa.enhance.PCRegistry; |
| import org.apache.openjpa.enhance.Reflection; |
| import org.apache.openjpa.kernel.AbstractBrokerFactory; |
| import org.apache.openjpa.kernel.Broker; |
| import org.apache.openjpa.kernel.DataCacheRetrieveMode; |
| import org.apache.openjpa.kernel.DataCacheStoreMode; |
| import org.apache.openjpa.kernel.DelegatingBroker; |
| import org.apache.openjpa.kernel.FetchConfiguration; |
| import org.apache.openjpa.kernel.FindCallbacks; |
| import org.apache.openjpa.kernel.OpCallbacks; |
| import org.apache.openjpa.kernel.OpenJPAStateManager; |
| import org.apache.openjpa.kernel.PreparedQuery; |
| import org.apache.openjpa.kernel.PreparedQueryCache; |
| import org.apache.openjpa.kernel.QueryFlushModes; |
| import org.apache.openjpa.kernel.QueryLanguages; |
| import org.apache.openjpa.kernel.Seq; |
| import org.apache.openjpa.kernel.jpql.JPQLParser; |
| import org.apache.openjpa.lib.log.Log; |
| import org.apache.openjpa.lib.util.Closeable; |
| import org.apache.openjpa.lib.util.Localizer; |
| import org.apache.openjpa.lib.util.StringUtil; |
| import org.apache.openjpa.meta.ClassMetaData; |
| import org.apache.openjpa.meta.FieldMetaData; |
| import org.apache.openjpa.meta.MetaDataRepository; |
| import org.apache.openjpa.meta.MultiQueryMetaData; |
| import org.apache.openjpa.meta.QueryMetaData; |
| import org.apache.openjpa.meta.SequenceMetaData; |
| import org.apache.openjpa.persistence.criteria.OpenJPACriteriaBuilder; |
| import org.apache.openjpa.persistence.criteria.OpenJPACriteriaQuery; |
| import org.apache.openjpa.persistence.validation.ValidationUtils; |
| import org.apache.openjpa.util.BlacklistClassResolver; |
| import org.apache.openjpa.util.ExceptionInfo; |
| import org.apache.openjpa.util.Exceptions; |
| import org.apache.openjpa.util.ImplHelper; |
| import org.apache.openjpa.util.RuntimeExceptionTranslator; |
| import org.apache.openjpa.util.UserException; |
| |
| |
| /** |
| * Implementation of {@link EntityManager} interface. |
| * |
| * @author Patrick Linskey |
| * @author Abe White |
| */ |
| public class EntityManagerImpl |
| implements OpenJPAEntityManagerSPI, Externalizable, |
| FindCallbacks, OpCallbacks, Closeable, OpenJPAEntityTransaction { |
| |
| private static final Localizer _loc = Localizer.forPackage(EntityManagerImpl.class); |
| private static final Object[] EMPTY_OBJECTS = new Object[0]; |
| |
| private static final String GET_LOCK_MODE = "getLockMode"; |
| private static final String LOCK = "lock"; |
| private static final String REFRESH = "refresh"; |
| |
| private DelegatingBroker _broker; |
| private EntityManagerFactoryImpl _emf; |
| private Map<FetchConfiguration,FetchPlan> _plans = new IdentityHashMap<>(1); |
| protected RuntimeExceptionTranslator _ret = PersistenceExceptions.getRollbackTranslator(this); |
| private boolean _convertPositionalParams = false; |
| private boolean _isJoinedToTransaction; |
| private Map<String, Object> properties; |
| |
| public EntityManagerImpl() { |
| // for Externalizable |
| } |
| |
| /** |
| * Constructor; supply factory and delegate. |
| */ |
| public EntityManagerImpl(EntityManagerFactoryImpl factory, Broker broker) { |
| initialize(factory, broker); |
| } |
| |
| private void initialize(EntityManagerFactoryImpl factory, Broker broker) { |
| _emf = factory; |
| _broker = new DelegatingBroker(broker, _ret); |
| _broker.setImplicitBehavior(this, _ret); |
| _broker.putUserObject(JPAFacadeHelper.EM_KEY, this); |
| _convertPositionalParams = |
| factory.getConfiguration().getCompatibilityInstance().getConvertPositionalParametersToNamed(); |
| } |
| |
| /** |
| * Broker delegate. |
| */ |
| public Broker getBroker() { |
| return _broker.getDelegate(); |
| } |
| |
| @Override |
| public OpenJPAEntityManagerFactory getEntityManagerFactory() { |
| return _emf; |
| } |
| |
| @Override |
| public OpenJPAConfiguration getConfiguration() { |
| return _broker.getConfiguration(); |
| } |
| |
| @Override |
| public FetchPlan getFetchPlan() { |
| assertNotCloseInvoked(); |
| _broker.lock(); |
| try { |
| FetchConfiguration fc = _broker.getFetchConfiguration(); |
| FetchPlan fp = _plans.get(fc); |
| if (fp == null) { |
| fp = _emf.toFetchPlan(_broker, fc); |
| _plans.put(fc, fp); |
| } |
| return fp; |
| } finally { |
| _broker.unlock(); |
| } |
| } |
| |
| @Override |
| public FetchPlan pushFetchPlan() { |
| return pushFetchPlan(null); |
| } |
| |
| public FetchPlan pushFetchPlan(FetchConfiguration fc) { |
| assertNotCloseInvoked(); |
| _broker.lock(); |
| try { |
| _broker.pushFetchConfiguration(fc); |
| return getFetchPlan(); |
| } finally { |
| _broker.unlock(); |
| } |
| } |
| |
| @Override |
| public void popFetchPlan() { |
| assertNotCloseInvoked(); |
| _broker.lock(); |
| try { |
| _plans.remove(_broker.getFetchConfiguration()); |
| _broker.popFetchConfiguration(); |
| } finally { |
| _broker.unlock(); |
| } |
| } |
| |
| @Override |
| public ConnectionRetainMode getConnectionRetainMode() { |
| return ConnectionRetainMode.fromKernelConstant( |
| _broker.getConnectionRetainMode()); |
| } |
| |
| @Override |
| public boolean isTransactionManaged() { |
| return _broker.isManaged(); |
| } |
| |
| @Override |
| public boolean isManaged() { |
| return _broker.isManaged(); |
| } |
| |
| @Override |
| public ManagedRuntime getManagedRuntime() { |
| return _broker.getManagedRuntime(); |
| } |
| |
| @Override |
| public boolean getSyncWithManagedTransactions() { |
| return _broker.getSyncWithManagedTransactions(); |
| } |
| |
| @Override |
| public void setSyncWithManagedTransactions(boolean sync) { |
| assertNotCloseInvoked(); |
| _broker.setSyncWithManagedTransactions(sync); |
| } |
| |
| @Override |
| public ClassLoader getClassLoader() { |
| return _broker.getClassLoader(); |
| } |
| |
| @Override |
| public String getConnectionUserName() { |
| return _broker.getConnectionUserName(); |
| } |
| |
| @Override |
| public String getConnectionPassword() { |
| return _broker.getConnectionPassword(); |
| } |
| |
| @Override |
| public boolean getMultithreaded() { |
| return _broker.getMultithreaded(); |
| } |
| |
| @Override |
| public void setMultithreaded(boolean multithreaded) { |
| assertNotCloseInvoked(); |
| _broker.setMultithreaded(multithreaded); |
| } |
| |
| @Override |
| public boolean getIgnoreChanges() { |
| return _broker.getIgnoreChanges(); |
| } |
| |
| @Override |
| public void setIgnoreChanges(boolean val) { |
| assertNotCloseInvoked(); |
| _broker.setIgnoreChanges(val); |
| } |
| |
| @Override |
| public boolean getNontransactionalRead() { |
| return _broker.getNontransactionalRead(); |
| } |
| |
| @Override |
| public void setNontransactionalRead(boolean val) { |
| assertNotCloseInvoked(); |
| _broker.setNontransactionalRead(val); |
| } |
| |
| @Override |
| public boolean getNontransactionalWrite() { |
| return _broker.getNontransactionalWrite(); |
| } |
| |
| @Override |
| public void setNontransactionalWrite(boolean val) { |
| assertNotCloseInvoked(); |
| _broker.setNontransactionalWrite(val); |
| } |
| |
| @Override |
| public boolean getOptimistic() { |
| return _broker.getOptimistic(); |
| } |
| |
| @Override |
| public void setOptimistic(boolean val) { |
| assertNotCloseInvoked(); |
| _broker.setOptimistic(val); |
| } |
| |
| @Override |
| public RestoreStateType getRestoreState() { |
| return RestoreStateType.fromKernelConstant(_broker.getRestoreState()); |
| } |
| |
| @Override |
| public void setRestoreState(RestoreStateType val) { |
| assertNotCloseInvoked(); |
| _broker.setRestoreState(val.toKernelConstant()); |
| } |
| |
| @Override |
| public void setRestoreState(int restore) { |
| assertNotCloseInvoked(); |
| _broker.setRestoreState(restore); |
| } |
| |
| @Override |
| public boolean getRetainState() { |
| return _broker.getRetainState(); |
| } |
| |
| @Override |
| public void setRetainState(boolean val) { |
| assertNotCloseInvoked(); |
| _broker.setRetainState(val); |
| } |
| |
| @Override |
| public AutoClearType getAutoClear() { |
| return AutoClearType.fromKernelConstant(_broker.getAutoClear()); |
| } |
| |
| @Override |
| public void setAutoClear(AutoClearType val) { |
| assertNotCloseInvoked(); |
| _broker.setAutoClear(val.toKernelConstant()); |
| } |
| |
| @Override |
| public void setAutoClear(int autoClear) { |
| assertNotCloseInvoked(); |
| _broker.setAutoClear(autoClear); |
| } |
| |
| @Override |
| public DetachStateType getDetachState() { |
| return DetachStateType.fromKernelConstant(_broker.getDetachState()); |
| } |
| |
| @Override |
| public void setDetachState(DetachStateType type) { |
| assertNotCloseInvoked(); |
| _broker.setDetachState(type.toKernelConstant()); |
| } |
| |
| @Override |
| public void setDetachState(int detach) { |
| assertNotCloseInvoked(); |
| _broker.setDetachState(detach); |
| } |
| |
| @Override |
| public EnumSet<AutoDetachType> getAutoDetach() { |
| return AutoDetachType.toEnumSet(_broker.getAutoDetach()); |
| } |
| |
| @Override |
| public void setAutoDetach(AutoDetachType flag) { |
| assertNotCloseInvoked(); |
| _broker.setAutoDetach(AutoDetachType.fromEnumSet(EnumSet.of(flag))); |
| } |
| |
| @Override |
| public void setAutoDetach(EnumSet<AutoDetachType> flags) { |
| assertNotCloseInvoked(); |
| _broker.setAutoDetach(AutoDetachType.fromEnumSet(flags)); |
| } |
| |
| @Override |
| public void setAutoDetach(int autoDetachFlags) { |
| assertNotCloseInvoked(); |
| _broker.setAutoDetach(autoDetachFlags); |
| } |
| |
| @Override |
| public void setAutoDetach(AutoDetachType value, boolean on) { |
| assertNotCloseInvoked(); |
| _broker.setAutoDetach(AutoDetachType.fromEnumSet(EnumSet.of(value)),on); |
| } |
| |
| @Override |
| public void setAutoDetach(int flag, boolean on) { |
| assertNotCloseInvoked(); |
| _broker.setAutoDetach(flag, on); |
| } |
| |
| @Override |
| public boolean getEvictFromStoreCache() { |
| return _broker.getEvictFromDataCache(); |
| } |
| |
| @Override |
| public void setEvictFromStoreCache(boolean evict) { |
| assertNotCloseInvoked(); |
| _broker.setEvictFromDataCache(evict); |
| } |
| |
| @Override |
| public boolean getPopulateStoreCache() { |
| return _broker.getPopulateDataCache(); |
| } |
| |
| @Override |
| public void setPopulateStoreCache(boolean cache) { |
| assertNotCloseInvoked(); |
| _broker.setPopulateDataCache(cache); |
| } |
| |
| @Override |
| public boolean isTrackChangesByType() { |
| return _broker.isTrackChangesByType(); |
| } |
| |
| @Override |
| public void setTrackChangesByType(boolean trackByType) { |
| assertNotCloseInvoked(); |
| _broker.setTrackChangesByType(trackByType); |
| } |
| |
| @Override |
| public boolean isLargeTransaction() { |
| return isTrackChangesByType(); |
| } |
| |
| @Override |
| public void setLargeTransaction(boolean value) { |
| setTrackChangesByType(value); |
| } |
| |
| @Override |
| public Object getUserObject(Object key) { |
| return _broker.getUserObject(key); |
| } |
| |
| @Override |
| public Object putUserObject(Object key, Object val) { |
| assertNotCloseInvoked(); |
| return _broker.putUserObject(key, val); |
| } |
| |
| @Override |
| public void addTransactionListener(Object listener) { |
| assertNotCloseInvoked(); |
| _broker.addTransactionListener(listener); |
| } |
| |
| @Override |
| public void removeTransactionListener(Object listener) { |
| assertNotCloseInvoked(); |
| _broker.removeTransactionListener(listener); |
| } |
| |
| @Override |
| public EnumSet<CallbackMode> getTransactionListenerCallbackModes() { |
| return CallbackMode.toEnumSet( |
| _broker.getTransactionListenerCallbackMode()); |
| } |
| |
| @Override |
| public void setTransactionListenerCallbackMode(CallbackMode mode) { |
| assertNotCloseInvoked(); |
| _broker.setTransactionListenerCallbackMode( |
| CallbackMode.fromEnumSet(EnumSet.of(mode))); |
| } |
| |
| @Override |
| public void setTransactionListenerCallbackMode(EnumSet<CallbackMode> modes){ |
| assertNotCloseInvoked(); |
| _broker.setTransactionListenerCallbackMode( |
| CallbackMode.fromEnumSet(modes)); |
| } |
| |
| @Override |
| public int getTransactionListenerCallbackMode() { |
| return _broker.getTransactionListenerCallbackMode(); |
| } |
| |
| @Override |
| public void setTransactionListenerCallbackMode(int callbackMode) { |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void addLifecycleListener(Object listener, Class... classes) { |
| assertNotCloseInvoked(); |
| _broker.addLifecycleListener(listener, classes); |
| } |
| |
| @Override |
| public void removeLifecycleListener(Object listener) { |
| assertNotCloseInvoked(); |
| _broker.removeLifecycleListener(listener); |
| } |
| |
| @Override |
| public EnumSet<CallbackMode> getLifecycleListenerCallbackModes() { |
| return CallbackMode.toEnumSet( |
| _broker.getLifecycleListenerCallbackMode()); |
| } |
| |
| @Override |
| public void setLifecycleListenerCallbackMode(CallbackMode mode) { |
| assertNotCloseInvoked(); |
| _broker.setLifecycleListenerCallbackMode( |
| CallbackMode.fromEnumSet(EnumSet.of(mode))); |
| } |
| |
| @Override |
| public void setLifecycleListenerCallbackMode(EnumSet<CallbackMode> modes) { |
| assertNotCloseInvoked(); |
| _broker.setLifecycleListenerCallbackMode( |
| CallbackMode.fromEnumSet(modes)); |
| } |
| |
| @Override |
| public int getLifecycleListenerCallbackMode() { |
| return _broker.getLifecycleListenerCallbackMode(); |
| } |
| |
| @Override |
| public void setLifecycleListenerCallbackMode(int callbackMode) { |
| assertNotCloseInvoked(); |
| _broker.setLifecycleListenerCallbackMode(callbackMode); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T getReference(Class<T> cls, Object oid) { |
| assertNotCloseInvoked(); |
| oid = _broker.newObjectId(cls, oid); |
| return (T) _broker.find(oid, false, this); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T find(Class<T> cls, Object oid) { |
| assertNotCloseInvoked(); |
| if (oid == null) |
| return null; |
| oid = _broker.newObjectId(cls, oid); |
| return (T) _broker.find(oid, true, this); |
| } |
| |
| @Override |
| public <T> T find(Class<T> cls, Object oid, LockModeType mode) { |
| return find(cls, oid, mode, null); |
| } |
| |
| @Override |
| public <T> T find(Class<T> cls, Object oid, |
| Map<String, Object> properties){ |
| return find(cls, oid, null, properties); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T find(Class<T> cls, Object oid, LockModeType mode, Map<String, Object> properties) { |
| assertNotCloseInvoked(); |
| properties = cloneProperties(properties); |
| configureCurrentCacheModes(pushFetchPlan(), properties); |
| configureCurrentFetchPlan(getFetchPlan(), properties, mode, true); |
| try { |
| oid = _broker.newObjectId(cls, oid); |
| return (T) _broker.find(oid, true, this); |
| } finally { |
| popFetchPlan(); |
| } |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T[] findAll(Class<T> cls, Object... oids) { |
| if (oids.length == 0) |
| return (T[]) Array.newInstance(cls, 0); |
| Collection<T> ret = findAll(cls, Arrays.asList(oids)); |
| return ret.toArray((T[]) Array.newInstance(cls, ret.size())); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> Collection<T> findAll(final Class<T> cls, Collection oids) { |
| assertNotCloseInvoked(); |
| Object[] objs = _broker.findAll(oids, true, new FindCallbacks() { |
| @Override |
| public Object processArgument(Object oid) { |
| return _broker.newObjectId(cls, oid); |
| } |
| |
| @Override |
| public Object processReturn(Object oid, OpenJPAStateManager sm) { |
| return EntityManagerImpl.this.processReturn(oid, sm); |
| } |
| }); |
| return (Collection<T>) Arrays.asList(objs); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T findCached(Class<T> cls, Object oid) { |
| assertNotCloseInvoked(); |
| return (T) _broker.findCached(_broker.newObjectId(cls, oid), this); |
| } |
| |
| @Override |
| public Class getObjectIdClass(Class cls) { |
| assertNotCloseInvoked(); |
| if (cls == null) |
| return null; |
| return JPAFacadeHelper.fromOpenJPAObjectIdClass |
| (_broker.getObjectIdType(cls)); |
| } |
| |
| @Override |
| public OpenJPAEntityTransaction getTransaction() { |
| if (_broker.isManaged()) |
| throw new InvalidStateException(_loc.get("get-managed-trans"), |
| null, null, false); |
| return this; |
| } |
| |
| @Override |
| public void joinTransaction() { |
| if (!_broker.syncWithManagedTransaction()) { |
| throw new TransactionRequiredException(_loc.get |
| ("no-managed-trans"), null, null, false); |
| } else { |
| _isJoinedToTransaction = true; |
| } |
| |
| assertNotCloseInvoked(); |
| if (!_broker.syncWithManagedTransaction()) |
| throw new TransactionRequiredException(_loc.get |
| ("no-managed-trans"), null, null, false); |
| } |
| |
| @Override |
| public boolean isJoinedToTransaction() { |
| return isActive() && _isJoinedToTransaction; |
| } |
| |
| @Override |
| public void begin() { |
| _broker.begin(); |
| } |
| |
| @Override |
| public void commit() { |
| try { |
| _broker.commit(); |
| } catch (RollbackException e) { |
| throw e; |
| } catch (IllegalStateException e) { |
| throw e; |
| } catch (Exception e) { |
| // Per JPA 2.0 spec, if the exception was due to a JSR-303 |
| // constraint violation, the ConstraintViolationException should be |
| // thrown. Since JSR-303 is optional, the cast to RuntimeException |
| // prevents the introduction of a runtime dependency on the BV API. |
| if (ValidationUtils.isConstraintViolationException(e)) |
| throw (RuntimeException)e; |
| // RollbackExceptions are special and aren't handled by the |
| // normal exception translator, since the spec says they |
| // should be thrown whenever the commit fails for any reason at |
| // all, wheras the exception translator handles exceptions that |
| // are caused for specific reasons |
| |
| // pass along the failed object if one is available. |
| Object failedObject = null; |
| if (e instanceof ExceptionInfo){ |
| failedObject = ((ExceptionInfo)e).getFailedObject(); |
| } |
| |
| throw new RollbackException(e).setFailedObject(failedObject); |
| } |
| } |
| |
| @Override |
| public void rollback() { |
| _broker.rollback(); |
| } |
| |
| @Override |
| public void commitAndResume() { |
| _broker.commitAndResume(); |
| } |
| |
| @Override |
| public void rollbackAndResume() { |
| _broker.rollbackAndResume(); |
| } |
| |
| @Override |
| public Throwable getRollbackCause() { |
| if (!isActive()) |
| throw new IllegalStateException(_loc.get("no-transaction") |
| .getMessage()); |
| |
| return _broker.getRollbackCause(); |
| } |
| |
| @Override |
| public boolean getRollbackOnly() { |
| if (!isActive()) |
| throw new IllegalStateException(_loc.get("no-transaction") |
| .getMessage()); |
| |
| return _broker.getRollbackOnly(); |
| } |
| |
| @Override |
| public void setRollbackOnly() { |
| _broker.setRollbackOnly(); |
| } |
| |
| @Override |
| public void setRollbackOnly(Throwable cause) { |
| _broker.setRollbackOnly(cause); |
| } |
| |
| @Override |
| public void setSavepoint(String name) { |
| assertNotCloseInvoked(); |
| _broker.setSavepoint(name); |
| } |
| |
| @Override |
| public void rollbackToSavepoint() { |
| assertNotCloseInvoked(); |
| _broker.rollbackToSavepoint(); |
| } |
| |
| @Override |
| public void rollbackToSavepoint(String name) { |
| assertNotCloseInvoked(); |
| _broker.rollbackToSavepoint(name); |
| } |
| |
| @Override |
| public void releaseSavepoint() { |
| assertNotCloseInvoked(); |
| _broker.releaseSavepoint(); |
| } |
| |
| @Override |
| public void releaseSavepoint(String name) { |
| assertNotCloseInvoked(); |
| _broker.releaseSavepoint(name); |
| } |
| |
| @Override |
| public void flush() { |
| assertNotCloseInvoked(); |
| _broker.assertOpen(); |
| _broker.assertActiveTransaction(); |
| _broker.flush(); |
| } |
| |
| @Override |
| public void preFlush() { |
| assertNotCloseInvoked(); |
| _broker.preFlush(); |
| } |
| |
| @Override |
| public void validateChanges() { |
| assertNotCloseInvoked(); |
| _broker.validateChanges(); |
| } |
| |
| @Override |
| public boolean isActive() { |
| return isOpen() && _broker.isActive(); |
| } |
| |
| @Override |
| public boolean isStoreActive() { |
| return _broker.isStoreActive(); |
| } |
| |
| @Override |
| public void beginStore() { |
| _broker.beginStore(); |
| } |
| |
| @Override |
| public boolean contains(Object entity) { |
| assertNotCloseInvoked(); |
| if (entity == null) |
| return false; |
| OpenJPAStateManager sm = _broker.getStateManager(entity); |
| if (sm == null |
| && !ImplHelper.isManagedType(getConfiguration(), entity.getClass())) |
| throw new ArgumentException(_loc.get("not-entity", |
| entity.getClass()), null, null, true); |
| return sm != null && !sm.isDeleted(); |
| } |
| |
| @Override |
| public boolean containsAll(Object... entities) { |
| for (Object entity : entities) |
| if (!contains(entity)) |
| return false; |
| return true; |
| } |
| |
| @Override |
| public boolean containsAll(Collection entities) { |
| for (Object entity : entities) |
| if (!contains(entity)) |
| return false; |
| return true; |
| } |
| |
| @Override |
| public void persist(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.persist(entity, this); |
| } |
| |
| @Override |
| public void persistAll(Object... entities) { |
| persistAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void persistAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.persistAll(entities, this); |
| } |
| |
| @Override |
| public void remove(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.delete(entity, this); |
| } |
| |
| @Override |
| public void removeAll(Object... entities) { |
| removeAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void removeAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.deleteAll(entities, this); |
| } |
| |
| @Override |
| public void release(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.release(entity, this); |
| } |
| |
| @Override |
| public void releaseAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.releaseAll(entities, this); |
| } |
| |
| @Override |
| public void releaseAll(Object... entities) { |
| releaseAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void refresh(Object entity) { |
| refresh(entity, null, null); |
| } |
| |
| @Override |
| public void refresh(Object entity, LockModeType mode) { |
| refresh(entity, mode, null); |
| } |
| |
| @Override |
| public void refresh(Object entity, Map<String, Object> properties) { |
| refresh(entity, null, properties); |
| } |
| |
| @Override |
| public void refresh(Object entity, LockModeType mode, Map<String, Object> properties) { |
| assertNotCloseInvoked(); |
| assertValidAttchedEntity(REFRESH, entity); |
| |
| _broker.assertWriteOperation(); |
| configureCurrentCacheModes(pushFetchPlan(), properties); |
| configureCurrentFetchPlan(getFetchPlan(), properties, mode, true); |
| DataCacheRetrieveMode rmode = getFetchPlan().getCacheRetrieveMode(); |
| if (DataCacheRetrieveMode.USE.equals(rmode) || rmode == null) { |
| getFetchPlan().setCacheRetrieveMode(DataCacheRetrieveMode.BYPASS); |
| } |
| try { |
| _broker.refresh(entity, this); |
| } finally { |
| popFetchPlan(); |
| } |
| } |
| |
| @Override |
| public void refreshAll() { |
| assertNotCloseInvoked(); |
| _broker.assertWriteOperation(); |
| _broker.refreshAll(_broker.getTransactionalObjects(), this); |
| } |
| |
| @Override |
| public void refreshAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.assertWriteOperation(); |
| _broker.refreshAll(entities, this); |
| } |
| |
| @Override |
| public void refreshAll(Object... entities) { |
| refreshAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void retrieve(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.retrieve(entity, true, this); |
| } |
| |
| @Override |
| public void retrieveAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.retrieveAll(entities, true, this); |
| } |
| |
| @Override |
| public void retrieveAll(Object... entities) { |
| retrieveAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void evict(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.evict(entity, this); |
| } |
| |
| @Override |
| public void evictAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.evictAll(entities, this); |
| } |
| |
| @Override |
| public void evictAll(Object... entities) { |
| evictAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void evictAll() { |
| assertNotCloseInvoked(); |
| _broker.evictAll(this); |
| } |
| |
| @Override |
| public void evictAll(Class cls) { |
| assertNotCloseInvoked(); |
| _broker.evictAll(_broker.newExtent(cls, true), this); |
| } |
| |
| @Override |
| public void evictAll(Extent extent) { |
| assertNotCloseInvoked(); |
| _broker.evictAll(((ExtentImpl) extent).getDelegate(), this); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T detachCopy(T entity) { |
| assertNotCloseInvoked(); |
| Compatibility compat = this.getConfiguration(). |
| getCompatibilityInstance(); |
| boolean copyOnDetach = compat.getCopyOnDetach(); |
| boolean cascadeWithDetach = compat.getCascadeWithDetach(); |
| // Set compatibility options to get 1.x detach behavior |
| compat.setCopyOnDetach(true); |
| compat.setCascadeWithDetach(true); |
| try { |
| T t = (T)_broker.detach(entity, this); |
| return t; |
| } finally { |
| // Reset compatibility options |
| compat.setCopyOnDetach(copyOnDetach); |
| compat.setCascadeWithDetach(cascadeWithDetach); |
| } |
| } |
| |
| @Override |
| public Object[] detachAll(Object... entities) { |
| assertNotCloseInvoked(); |
| return _broker.detachAll(Arrays.asList(entities), this); |
| } |
| |
| @Override |
| public Collection detachAll(Collection entities) { |
| assertNotCloseInvoked(); |
| return Arrays.asList(_broker.detachAll(entities, this)); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T merge(T entity) { |
| assertNotCloseInvoked(); |
| return (T) _broker.attach(entity, true, this); |
| } |
| |
| @Override |
| public Object[] mergeAll(Object... entities) { |
| if (entities.length == 0) |
| return EMPTY_OBJECTS; |
| return mergeAll(Arrays.asList(entities)).toArray(); |
| } |
| |
| @Override |
| public Collection mergeAll(Collection entities) { |
| assertNotCloseInvoked(); |
| return Arrays.asList(_broker.attachAll(entities, true, this)); |
| } |
| |
| @Override |
| public void transactional(Object entity, boolean updateVersion) { |
| assertNotCloseInvoked(); |
| _broker.transactional(entity, updateVersion, this); |
| } |
| |
| @Override |
| public void transactionalAll(Collection objs, boolean updateVersion) { |
| assertNotCloseInvoked(); |
| _broker.transactionalAll(objs, updateVersion, this); |
| } |
| |
| @Override |
| public void transactionalAll(Object[] objs, boolean updateVersion) { |
| assertNotCloseInvoked(); |
| _broker.transactionalAll(Arrays.asList(objs), updateVersion, this); |
| } |
| |
| @Override |
| public void nontransactional(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.nontransactional(entity, this); |
| } |
| |
| @Override |
| public void nontransactionalAll(Collection objs) { |
| assertNotCloseInvoked(); |
| _broker.nontransactionalAll(objs, this); |
| } |
| |
| @Override |
| public void nontransactionalAll(Object[] objs) { |
| assertNotCloseInvoked(); |
| _broker.nontransactionalAll(Arrays.asList(objs), this); |
| } |
| |
| @Override |
| public Generator getNamedGenerator(String name) { |
| assertNotCloseInvoked(); |
| try { |
| SequenceMetaData meta = _broker.getConfiguration(). |
| getMetaDataRepositoryInstance().getSequenceMetaData(name, |
| _broker.getClassLoader(), true); |
| Seq seq = meta.getInstance(_broker.getClassLoader()); |
| return new GeneratorImpl(seq, name, _broker, null); |
| } catch (RuntimeException re) { |
| throw PersistenceExceptions.toPersistenceException(re); |
| } |
| } |
| |
| @Override |
| public Generator getIdGenerator(Class forClass) { |
| assertNotCloseInvoked(); |
| try { |
| ClassMetaData meta = _broker.getConfiguration(). |
| getMetaDataRepositoryInstance().getMetaData(forClass, |
| _broker.getClassLoader(), true); |
| Seq seq = _broker.getIdentitySequence(meta); |
| return (seq == null) ? null : new GeneratorImpl(seq, null, _broker, |
| meta); |
| } catch (Exception e) { |
| throw PersistenceExceptions.toPersistenceException(e); |
| } |
| } |
| |
| @Override |
| public Generator getFieldGenerator(Class forClass, String fieldName) { |
| assertNotCloseInvoked(); |
| try { |
| ClassMetaData meta = _broker.getConfiguration(). |
| getMetaDataRepositoryInstance().getMetaData(forClass, |
| _broker.getClassLoader(), true); |
| FieldMetaData fmd = meta.getField(fieldName); |
| if (fmd == null) |
| throw new ArgumentException(_loc.get("no-named-field", |
| forClass, fieldName), null, null, false); |
| |
| Seq seq = _broker.getValueSequence(fmd); |
| return (seq == null) ? null : new GeneratorImpl(seq, null, _broker, |
| meta); |
| } catch (Exception e) { |
| throw PersistenceExceptions.toPersistenceException(e); |
| } |
| } |
| |
| @Override |
| public <T> Extent<T> createExtent(Class<T> cls, boolean subclasses) { |
| assertNotCloseInvoked(); |
| return new ExtentImpl<T>(this, _broker.newExtent(cls, subclasses)); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> TypedQuery<T> createQuery(String query, Class<T> resultClass) { |
| checkTuple(resultClass); |
| return createQuery(query).setResultClass(resultClass); |
| } |
| |
| private <T> void checkTuple(Class<T> resultClass) { |
| if (Tuple.class == resultClass) { |
| throw new PersistenceException("Tuple is not a valid type", null, null, true); |
| } |
| } |
| |
| @Override |
| public OpenJPAQuery createQuery(String query) { |
| return createQuery(JPQLParser.LANG_JPQL, query); |
| } |
| |
| @Override |
| public OpenJPAQuery createQuery(String language, String query) { |
| assertNotCloseInvoked(); |
| try { |
| // We need |
| if (query != null && _convertPositionalParams && JPQLParser.LANG_JPQL.equals(language)) { |
| query = query.replaceAll("[\\?]", "\\:_"); |
| } |
| String qid = query; |
| PreparedQuery pq = JPQLParser.LANG_JPQL.equals(language) |
| ? getPreparedQuery(qid) : null; |
| org.apache.openjpa.kernel.Query q = (pq == null || !pq.isInitialized()) |
| ? _broker.newQuery(language, query) |
| : _broker.newQuery(pq.getLanguage(), pq); |
| // have to validate JPQL according to spec |
| if (pq == null && JPQLParser.LANG_JPQL.equals(language)) |
| q.compile(); |
| if (pq != null) { |
| pq.setInto(q); |
| } |
| return newQueryImpl(q, null).setId(qid); |
| } catch (RuntimeException re) { |
| throw PersistenceExceptions.toPersistenceException(re); |
| } |
| } |
| |
| @Override |
| public OpenJPAQuery createQuery(Query query) { |
| if (query == null) |
| return createQuery((String) null); |
| assertNotCloseInvoked(); |
| org.apache.openjpa.kernel.Query q = ((QueryImpl) query).getDelegate(); |
| return newQueryImpl(_broker.newQuery(q.getLanguage(), q), null); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) { |
| checkTuple(resultClass); |
| return createNamedQuery(name).setResultClass(resultClass); |
| } |
| |
| @Override |
| public OpenJPAQuery createNamedQuery(String name) { |
| assertNotCloseInvoked(); |
| _broker.assertOpen(); |
| try { |
| QueryMetaData meta = _broker.getConfiguration(). |
| getMetaDataRepositoryInstance().getQueryMetaData(null, name, |
| _broker.getClassLoader(), true); |
| String qid = meta.getQueryString(); |
| |
| PreparedQuery pq = JPQLParser.LANG_JPQL.equals(meta.getLanguage()) ? getPreparedQuery(qid) : null; |
| org.apache.openjpa.kernel.Query del = |
| (pq == null || !pq.isInitialized()) ? _broker.newQuery(meta.getLanguage(), meta.getQueryString()) |
| : _broker.newQuery(pq.getLanguage(), pq); |
| |
| if (pq != null) { |
| pq.setInto(del); |
| } else { |
| meta.setInto(del); |
| del.compile(); |
| } |
| |
| OpenJPAQuery q = newQueryImpl(del, meta).setId(qid); |
| String[] hints = meta.getHintKeys(); |
| Object[] values = meta.getHintValues(); |
| for (int i = 0; i < hints.length; i++) |
| q.setHint(hints[i], values[i]); |
| return q; |
| } catch (RuntimeException re) { |
| throw PersistenceExceptions.toPersistenceException(re); |
| } |
| } |
| |
| @Override |
| public OpenJPAQuery createNativeQuery(String query) { |
| validateSQL(query); |
| return createQuery(QueryLanguages.LANG_SQL, query); |
| } |
| |
| @Override |
| public OpenJPAQuery createNativeQuery(String query, Class cls) { |
| checkTuple(cls); |
| return createNativeQuery(query).setResultClass(cls); |
| } |
| |
| @Override |
| public OpenJPAQuery createNativeQuery(String query, String mappingName) { |
| assertNotCloseInvoked(); |
| validateSQL(query); |
| org.apache.openjpa.kernel.Query kernelQuery = _broker.newQuery( |
| QueryLanguages.LANG_SQL, query); |
| kernelQuery.setResultMapping(null, mappingName); |
| return newQueryImpl(kernelQuery, null); |
| } |
| |
| @Override |
| public StoredProcedureQuery createNamedStoredProcedureQuery(String name) { |
| QueryMetaData meta = getQueryMetadata(name); |
| if (!MultiQueryMetaData.class.isInstance(meta)) { |
| throw new RuntimeException(name + " is not an identifier for a Stored Procedure Query"); |
| } |
| return newProcedure(((MultiQueryMetaData)meta).getProcedureName(), (MultiQueryMetaData)meta); |
| } |
| |
| @Override |
| public StoredProcedureQuery createStoredProcedureQuery(String procedureName) { |
| return newProcedure(procedureName, null); |
| } |
| |
| @Override |
| public StoredProcedureQuery createStoredProcedureQuery(String procedureName, Class... resultClasses) { |
| String tempName = "StoredProcedure-"+System.nanoTime(); |
| MultiQueryMetaData meta = new MultiQueryMetaData(null, tempName, procedureName, true); |
| for (Class<?> res : resultClasses) { |
| meta.addComponent(res); |
| } |
| return newProcedure(procedureName, meta); |
| } |
| |
| @Override |
| public StoredProcedureQuery createStoredProcedureQuery(String procedureName, String... resultSetMappings) { |
| String tempName = "StoredProcedure-"+System.nanoTime(); |
| MultiQueryMetaData meta = new MultiQueryMetaData(null, tempName, procedureName, true); |
| for (String mapping : resultSetMappings) { |
| meta.addComponent(mapping); |
| } |
| return newProcedure(procedureName, meta); |
| } |
| |
| /** |
| * Creates a query to execute a Stored Procedure. |
| * <br> |
| * Construction of a {@link StoredProcedureQuery} object is a three step process |
| * <LI> |
| * <LI>a {@link org.apache.openjpa.kernel.Query kernel query} {@code kQ} is created for |
| * {@link QueryLanguages#LANG_SQL SQL} language with the string {@code S} |
| * <LI>a {@link QueryImpl facade query} {@code fQ} is created that delegates to the kernel query {@code kQ} |
| * <LI>a {@link StoredProcedureQueryImpl stored procedure query} is created that delegates to the facade query |
| * {@code fQ}. |
| * <br> |
| * |
| */ |
| private StoredProcedureQuery newProcedure(String procedureName, MultiQueryMetaData meta) { |
| org.apache.openjpa.kernel.QueryImpl kernelQuery = (org.apache.openjpa.kernel.QueryImpl) |
| _broker.newQuery(QueryLanguages.LANG_STORED_PROC, procedureName); |
| kernelQuery.getStoreQuery().setQuery(meta); |
| if (meta != null) { |
| getConfiguration().getMetaDataRepositoryInstance().addQueryMetaData(meta); |
| kernelQuery.setResultMapping(null, meta.getResultSetMappingName()); |
| } |
| return new StoredProcedureQueryImpl(procedureName, meta, new QueryImpl(this, _ret, kernelQuery, meta)); |
| } |
| |
| protected <T> QueryImpl<T> newQueryImpl(org.apache.openjpa.kernel.Query kernelQuery, QueryMetaData qmd) { |
| return new QueryImpl<>(this, _ret, kernelQuery, qmd); |
| } |
| |
| /** |
| * @Deprecated -- Use org.apache.openjpa.persistence.EntityManagerImpl.newQueryImpl(Query kernelQuery, QueryMetaData |
| * qmd) |
| * <br> |
| * Leave this method here as extenders of OpenJPA might depend on this hook to allow interception of |
| * query creation |
| */ |
| protected <T> QueryImpl<T> newQueryImpl(org.apache.openjpa.kernel.Query kernelQuery) { |
| return new QueryImpl<>(this, _ret, kernelQuery, null); |
| } |
| |
| /** |
| * Validate that the user provided SQL. |
| */ |
| protected void validateSQL(String query) { |
| if (StringUtil.trimToNull(query) == null) |
| throw new ArgumentException(_loc.get("no-sql"), null, null, false); |
| } |
| |
| PreparedQueryCache getPreparedQueryCache() { |
| return _broker.getCachePreparedQuery() ? |
| getConfiguration().getQuerySQLCacheInstance() : null; |
| } |
| |
| /** |
| * Gets the prepared query cached by the given key. |
| * |
| * @return the cached PreparedQuery or null if none exists. |
| */ |
| PreparedQuery getPreparedQuery(String id) { |
| PreparedQueryCache cache = getPreparedQueryCache(); |
| return (cache == null) ? null : cache.get(id); |
| } |
| |
| @Override |
| public void setFlushMode(FlushModeType flushMode) { |
| assertNotCloseInvoked(); |
| _broker.assertOpen(); |
| _broker.getFetchConfiguration().setFlushBeforeQueries |
| (toFlushBeforeQueries(flushMode)); |
| } |
| |
| @Override |
| public FlushModeType getFlushMode() { |
| assertNotCloseInvoked(); |
| _broker.assertOpen(); |
| return fromFlushBeforeQueries(_broker.getFetchConfiguration(). |
| getFlushBeforeQueries()); |
| } |
| |
| /** |
| * Translate our internal flush constant to a flush mode enum value. |
| */ |
| static FlushModeType fromFlushBeforeQueries(int flush) { |
| switch (flush) { |
| case QueryFlushModes.FLUSH_TRUE: |
| return FlushModeType.AUTO; |
| case QueryFlushModes.FLUSH_FALSE: |
| return FlushModeType.COMMIT; |
| default: |
| return null; |
| } |
| } |
| |
| /** |
| * Translate a flush mode enum value to our internal flush constant. |
| */ |
| static int toFlushBeforeQueries(FlushModeType flushMode) { |
| // choose default for null |
| if (flushMode == null) |
| return QueryFlushModes.FLUSH_WITH_CONNECTION; |
| if (flushMode == FlushModeType.AUTO) |
| return QueryFlushModes.FLUSH_TRUE; |
| if (flushMode == FlushModeType.COMMIT) |
| return QueryFlushModes.FLUSH_FALSE; |
| throw new ArgumentException(flushMode.toString(), null, null, false); |
| } |
| |
| /** |
| * Used by Java EE Containers that wish to pool OpenJPA EntityManagers. The specification |
| * doesn't allow the closing of connections with the clear() method. By introducing this |
| * new method, we can do additional processing (and maybe more efficient processing) to |
| * properly prepare an EM for pooling. |
| * |
| * @deprecated - use {@link clear()} instead. |
| */ |
| @Deprecated |
| public void prepareForPooling() { |
| assertNotCloseInvoked(); |
| clear(); |
| // Do not close connection if ConnectionRetainMode is set to Always... |
| if (getConnectionRetainMode() != ConnectionRetainMode.ALWAYS) { |
| _broker.lock(); // since this direct close path is not protected... |
| try { |
| _broker.getStoreManager().close(); |
| } finally { |
| _broker.unlock(); |
| } |
| } |
| } |
| |
| @Override |
| public void clear() { |
| assertNotCloseInvoked(); |
| _broker.detachAll(this, false); |
| _plans.clear(); |
| } |
| |
| @Override |
| public Object getDelegate() { |
| _broker.assertOpen(); |
| assertNotCloseInvoked(); |
| return this; |
| } |
| |
| @Override |
| public LockModeType getLockMode(Object entity) { |
| assertNotCloseInvoked(); |
| _broker.assertActiveTransaction(); |
| assertValidAttchedEntity(GET_LOCK_MODE, entity); |
| return MixedLockLevelsHelper.fromLockLevel( |
| _broker.getLockLevel(entity)); |
| } |
| |
| @Override |
| public void lock(Object entity, LockModeType mode) { |
| lock(entity, mode, -1); |
| } |
| |
| @Override |
| public void lock(Object entity) { |
| assertNotCloseInvoked(); |
| assertValidAttchedEntity(LOCK, entity); |
| _broker.lock(entity, this); |
| } |
| |
| @Override |
| public void lock(Object entity, LockModeType mode, int timeout) { |
| assertNotCloseInvoked(); |
| assertValidAttchedEntity(LOCK, entity); |
| |
| configureCurrentFetchPlan(pushFetchPlan(), null, mode, false); |
| try { |
| _broker.lock(entity, MixedLockLevelsHelper.toLockLevel(mode), timeout, this); |
| } finally { |
| popFetchPlan(); |
| } |
| } |
| |
| @Override |
| public void lock(Object entity, LockModeType mode, Map<String, Object> properties) { |
| assertNotCloseInvoked(); |
| assertValidAttchedEntity(LOCK, entity); |
| _broker.assertActiveTransaction(); |
| properties = cloneProperties(properties); |
| configureCurrentCacheModes(pushFetchPlan(), properties); |
| configureCurrentFetchPlan(getFetchPlan(), properties, mode, false); |
| try { |
| _broker.lock(entity, MixedLockLevelsHelper.toLockLevel(mode), |
| _broker.getFetchConfiguration().getLockTimeout(), this); |
| } finally { |
| popFetchPlan(); |
| } |
| } |
| |
| @Override |
| public void lockAll(Collection entities) { |
| assertNotCloseInvoked(); |
| _broker.lockAll(entities, this); |
| } |
| |
| @Override |
| public void lockAll(Collection entities, LockModeType mode, int timeout) { |
| assertNotCloseInvoked(); |
| _broker.lockAll(entities, MixedLockLevelsHelper.toLockLevel(mode), |
| timeout, this); |
| } |
| |
| @Override |
| public void lockAll(Object... entities) { |
| lockAll(Arrays.asList(entities)); |
| } |
| |
| @Override |
| public void lockAll(Object[] entities, LockModeType mode, int timeout) { |
| lockAll(Arrays.asList(entities), mode, timeout); |
| } |
| |
| @Override |
| public boolean cancelAll() { |
| return _broker.cancelAll(); |
| } |
| |
| @Override |
| public Object getConnection() { |
| return _broker.getConnection(); |
| } |
| |
| @Override |
| public Collection getManagedObjects() { |
| return _broker.getManagedObjects(); |
| } |
| |
| @Override |
| public Collection getTransactionalObjects() { |
| return _broker.getTransactionalObjects(); |
| } |
| |
| @Override |
| public Collection getPendingTransactionalObjects() { |
| return _broker.getPendingTransactionalObjects(); |
| } |
| |
| @Override |
| public Collection getDirtyObjects() { |
| return _broker.getDirtyObjects(); |
| } |
| |
| @Override |
| public boolean getOrderDirtyObjects() { |
| return _broker.getOrderDirtyObjects(); |
| } |
| |
| @Override |
| public void setOrderDirtyObjects(boolean order) { |
| assertNotCloseInvoked(); |
| _broker.setOrderDirtyObjects(order); |
| } |
| |
| @Override |
| public void dirtyClass(Class cls) { |
| assertNotCloseInvoked(); |
| _broker.dirtyType(cls); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public Collection<Class> getPersistedClasses() { |
| return (Collection<Class>) _broker.getPersistedTypes(); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public Collection<Class> getUpdatedClasses() { |
| return (Collection<Class>) _broker.getUpdatedTypes(); |
| } |
| |
| @Override |
| @SuppressWarnings("unchecked") |
| public Collection<Class> getRemovedClasses() { |
| return (Collection<Class>) _broker.getDeletedTypes(); |
| } |
| |
| @Override |
| public <T> T createInstance(Class<T> cls) { |
| assertNotCloseInvoked(); |
| return (T) _broker.newInstance(cls); |
| } |
| |
| @Override |
| public void close() { |
| assertNotCloseInvoked(); |
| Log log = _emf.getConfiguration().getLog(OpenJPAConfiguration.LOG_RUNTIME); |
| if (log.isTraceEnabled()) { |
| log.trace(this + ".close() invoked."); |
| } |
| _broker.close(); |
| _plans.clear(); |
| } |
| |
| @Override |
| public boolean isOpen() { |
| return !_broker.isCloseInvoked(); |
| } |
| |
| @Override |
| public void dirty(Object o, String field) { |
| assertNotCloseInvoked(); |
| OpenJPAStateManager sm = _broker.getStateManager(o); |
| try { |
| if (sm != null) |
| sm.dirty(field); |
| } catch (Exception e) { |
| throw PersistenceExceptions.toPersistenceException(e); |
| } |
| } |
| |
| @Override |
| public Object getObjectId(Object o) { |
| assertNotCloseInvoked(); |
| return JPAFacadeHelper.fromOpenJPAObjectId(_broker.getObjectId(o)); |
| } |
| |
| @Override |
| public boolean isDirty(Object o) { |
| assertNotCloseInvoked(); |
| return _broker.isDirty(o); |
| } |
| |
| @Override |
| public boolean isTransactional(Object o) { |
| assertNotCloseInvoked(); |
| return _broker.isTransactional(o); |
| } |
| |
| @Override |
| public boolean isPersistent(Object o) { |
| assertNotCloseInvoked(); |
| return _broker.isPersistent(o); |
| } |
| |
| @Override |
| public boolean isNewlyPersistent(Object o) { |
| assertNotCloseInvoked(); |
| return _broker.isNew(o); |
| } |
| |
| @Override |
| public boolean isRemoved(Object o) { |
| assertNotCloseInvoked(); |
| return _broker.isDeleted(o); |
| } |
| |
| @Override |
| public boolean isDetached(Object entity) { |
| assertNotCloseInvoked(); |
| return _broker.isDetached(entity); |
| } |
| |
| @Override |
| public Object getVersion(Object o) { |
| assertNotCloseInvoked(); |
| return _broker.getVersion(o); |
| } |
| |
| /** |
| * Throw appropriate exception if close has been invoked but the broker |
| * is still open. We test only for this because if the broker is already |
| * closed, it will throw its own more informative exception when we |
| * delegate the pending operation to it. |
| */ |
| protected void assertNotCloseInvoked() { |
| if (!_broker.isClosed() && _broker.isCloseInvoked()) |
| throw new InvalidStateException(_loc.get("close-invoked"), null, |
| null, true); |
| } |
| |
| /** |
| * Throw IllegalArgumentExceptionif if entity is not a valid entity or |
| * if it is detached. |
| */ |
| void assertValidAttchedEntity(String call, Object entity) { |
| OpenJPAStateManager sm = _broker.getStateManager(entity); |
| if (sm == null || !sm.isPersistent() || sm.isDetached() || (call.equals(REFRESH) && sm.isDeleted())) { |
| throw new IllegalArgumentException(_loc.get("invalid_entity_argument", |
| call, entity == null ? "null" : Exceptions.toString(entity)).getMessage()); |
| } |
| } |
| |
| //////////////////////////////// |
| // FindCallbacks implementation |
| //////////////////////////////// |
| |
| @Override |
| public Object processArgument(Object arg) { |
| return arg; |
| } |
| |
| @Override |
| public Object processReturn(Object oid, OpenJPAStateManager sm) { |
| return (sm == null || sm.isDeleted()) ? null : sm.getManagedInstance(); |
| } |
| |
| ////////////////////////////// |
| // OpCallbacks implementation |
| ////////////////////////////// |
| |
| @Override |
| public int processArgument(int op, Object obj, OpenJPAStateManager sm) { |
| switch (op) { |
| case OP_DELETE: |
| // cascade through non-persistent non-detached instances |
| if (sm == null && !_broker.isDetached(obj)) |
| return ACT_CASCADE; |
| if (sm != null && !sm.isDetached() && !sm.isPersistent()) |
| return ACT_CASCADE; |
| // ignore deleted instances |
| if (sm != null && sm.isDeleted()) |
| return ACT_NONE; |
| break; |
| case OP_ATTACH: |
| // die on removed |
| if (sm != null && sm.isDeleted()) |
| throw new UserException(_loc.get("removed", |
| Exceptions.toString(obj))).setFailedObject(obj); |
| // cascade through managed instances |
| if (sm != null && !sm.isDetached()) |
| return ACT_CASCADE; |
| break; |
| case OP_REFRESH: |
| // die on unmanaged instances |
| if (sm == null) |
| throw new UserException(_loc.get("not-managed", |
| Exceptions.toString(obj))).setFailedObject(obj); |
| break; |
| case OP_DETACH: |
| if (sm == null || !sm.isPersistent() || sm.isDetached()) |
| return ACT_NONE; |
| break; |
| } |
| return ACT_RUN | ACT_CASCADE; |
| } |
| |
| @Override |
| public int hashCode() { |
| return (_broker == null) ? 0 : _broker.hashCode(); |
| } |
| |
| @Override |
| public boolean equals(Object other) { |
| if (other == this) |
| return true; |
| if ((other == null) || (other.getClass() != this.getClass())) |
| return false; |
| if (_broker == null) |
| return false; |
| return _broker.equals(((EntityManagerImpl) other)._broker); |
| } |
| |
| @Override |
| public void readExternal(ObjectInput in) |
| throws IOException, ClassNotFoundException { |
| try { |
| _ret = PersistenceExceptions.getRollbackTranslator(this); |
| |
| // this assumes that serialized Brokers are from something |
| // that extends AbstractBrokerFactory. |
| Object factoryKey = in.readObject(); |
| AbstractBrokerFactory factory = |
| AbstractBrokerFactory.getPooledFactoryForKey(factoryKey); |
| byte[] brokerBytes = (byte[]) in.readObject(); |
| ObjectInputStream innerIn = new BrokerBytesInputStream(brokerBytes, |
| factory.getConfiguration()); |
| |
| Broker broker = (Broker) innerIn.readObject(); |
| EntityManagerFactoryImpl emf = (EntityManagerFactoryImpl) |
| JPAFacadeHelper.toEntityManagerFactory( |
| broker.getBrokerFactory()); |
| broker.putUserObject(JPAFacadeHelper.EM_KEY, this); |
| initialize(emf, broker); |
| } catch (RuntimeException re) { |
| try { |
| re = _ret.translate(re); |
| } catch (Exception e) { |
| // ignore |
| } |
| throw re; |
| } |
| } |
| |
| @Override |
| public void writeExternal(ObjectOutput out) throws IOException { |
| try { |
| // this requires that only AbstractBrokerFactory-sourced |
| // brokers can be serialized |
| Object factoryKey = ((AbstractBrokerFactory) _broker |
| .getBrokerFactory()).getPoolKey(); |
| out.writeObject(factoryKey); |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| ObjectOutputStream innerOut = new ObjectOutputStream(baos); |
| _broker.getDelegate().putUserObject(JPAFacadeHelper.EM_KEY, null); |
| innerOut.writeObject(_broker.getDelegate()); |
| innerOut.flush(); |
| out.writeObject(baos.toByteArray()); |
| } catch (RuntimeException re) { |
| try { |
| re = _ret.translate(re); |
| } catch (Exception e) { |
| // ignore |
| } |
| throw re; |
| } |
| } |
| |
| public void setProperties(final Map<String, Object> emEmptyPropsProperties) { |
| this.properties = emEmptyPropsProperties; |
| } |
| |
| private static class BrokerBytesInputStream extends ObjectInputStream { |
| |
| private OpenJPAConfiguration conf; |
| |
| BrokerBytesInputStream(byte[] bytes, OpenJPAConfiguration conf) |
| throws IOException { |
| super(new ByteArrayInputStream(bytes)); |
| if (conf == null) |
| throw new IllegalArgumentException( |
| "Illegal null argument to ObjectInputStreamWithLoader"); |
| this.conf = conf; |
| } |
| |
| /** |
| * Make a primitive array class |
| */ |
| private Class primitiveType(char type) { |
| switch (type) { |
| case 'B': return byte.class; |
| case 'C': return char.class; |
| case 'D': return double.class; |
| case 'F': return float.class; |
| case 'I': return int.class; |
| case 'J': return long.class; |
| case 'S': return short.class; |
| case 'Z': return boolean.class; |
| default: return null; |
| } |
| } |
| |
| @Override |
| protected Class<?> resolveClass(ObjectStreamClass classDesc) |
| throws IOException, ClassNotFoundException { |
| |
| String cname = BlacklistClassResolver.DEFAULT.check(classDesc.getName()); |
| if (cname.startsWith("[")) { |
| // An array |
| Class<?> component; // component class |
| int dcount; // dimension |
| for (dcount=1; cname.charAt(dcount)=='['; dcount++) ; |
| if (cname.charAt(dcount) == 'L') { |
| component = lookupClass(cname.substring(dcount+1, |
| cname.length()-1)); |
| } else { |
| if (cname.length() != dcount+1) { |
| throw new ClassNotFoundException(cname);// malformed |
| } |
| component = primitiveType(cname.charAt(dcount)); |
| } |
| int dim[] = new int[dcount]; |
| for (int i=0; i<dcount; i++) { |
| dim[i]=0; |
| } |
| return Array.newInstance(component, dim).getClass(); |
| } else { |
| return lookupClass(cname); |
| } |
| } |
| |
| /** |
| * If this is a generated subclass, look up the corresponding Class |
| * object via metadata. |
| */ |
| private Class<?> lookupClass(String className) |
| throws ClassNotFoundException { |
| try { |
| return Class.forName(className); |
| } catch (ClassNotFoundException e) { |
| if (PCEnhancer.isPCSubclassName(className)) { |
| String superName = PCEnhancer.toManagedTypeName(className); |
| ClassMetaData[] metas = conf.getMetaDataRepositoryInstance() |
| .getMetaDatas(); |
| for (int i = 0; i < metas.length; i++) { |
| if (superName.equals( |
| metas[i].getDescribedType().getName())) { |
| return PCRegistry.getPCType( |
| metas[i].getDescribedType()); |
| } |
| } |
| |
| // if it's not found, try to look for it anyways |
| return Class.forName(className); |
| } else { |
| throw e; |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void detach(Object entity) { |
| if (entity == null) |
| throw new IllegalArgumentException(_loc.get("null-detach").getMessage()); |
| assertNotCloseInvoked(); |
| _broker.detach(entity, this); |
| } |
| |
| /** |
| * Create a query from the given CritriaQuery. |
| * Compile to register the parameters in this query. |
| */ |
| @Override |
| public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) { |
| ((OpenJPACriteriaQuery<T>)criteriaQuery).compile(); |
| |
| org.apache.openjpa.kernel.Query kernelQuery =_broker.newQuery(OpenJPACriteriaBuilder.LANG_CRITERIA, criteriaQuery); |
| |
| QueryImpl<T> facadeQuery = newQueryImpl(kernelQuery, null).setId(criteriaQuery.toString()); |
| Set<ParameterExpression<?>> params = criteriaQuery.getParameters(); |
| |
| for (ParameterExpression<?> param : params) { |
| facadeQuery.declareParameter(param, param); |
| } |
| return facadeQuery; |
| } |
| |
| @Override |
| public Query createQuery(CriteriaUpdate updateQuery) { |
| throw new UnsupportedOperationException("JPA 2.1"); |
| } |
| |
| @Override |
| public Query createQuery(CriteriaDelete deleteQuery) { |
| throw new UnsupportedOperationException("JPA 2.1"); |
| } |
| |
| @Override |
| public OpenJPAQuery createDynamicQuery( |
| org.apache.openjpa.persistence.query.QueryDefinition qdef) { |
| String jpql = _emf.getDynamicQueryBuilder().toJPQL(qdef); |
| return createQuery(jpql); |
| } |
| |
| /** |
| * Get the properties used currently by this entity manager. |
| * The property keys and their values are harvested from kernel artifacts namely |
| * the Broker and FetchPlan by reflection. |
| * These property keys and values that denote the bean properties/values of the kernel artifacts |
| * are converted to the original keys/values that user used to set the properties. |
| * |
| */ |
| @Override |
| public Map<String, Object> getProperties() { |
| if (properties != null) { |
| return properties; |
| } |
| Map<String,Object> props = _broker.getProperties(); |
| for (String s : _broker.getSupportedProperties()) { |
| String kernelKey = getBeanPropertyName(s); |
| Method getter = Reflection.findGetter(this.getClass(), kernelKey, false); |
| if (getter != null) { |
| String userKey = JPAProperties.getUserName(kernelKey); |
| Object kvalue = Reflection.get(this, getter); |
| props.put(userKey.equals(kernelKey) ? s : userKey, JPAProperties.convertToUserValue(userKey, kvalue)); |
| } |
| } |
| FetchPlan fetch = getFetchPlan(); |
| Class<?> fetchType = fetch.getClass(); |
| Set<String> fProperties = Reflection.getBeanStylePropertyNames(fetchType); |
| for (String s : fProperties) { |
| String kernelKey = getBeanPropertyName(s); |
| Method getter = Reflection.findGetter(fetchType, kernelKey, false); |
| if (getter != null) { |
| String userKey = JPAProperties.getUserName(kernelKey); |
| Object kvalue = Reflection.get(fetch, getter); |
| props.put(userKey.equals(kernelKey) ? s : userKey, JPAProperties.convertToUserValue(userKey, kvalue)); |
| } |
| } |
| return props; |
| } |
| |
| @Override |
| public OpenJPACriteriaBuilder getCriteriaBuilder() { |
| return _emf.getCriteriaBuilder(); |
| } |
| |
| @Override |
| public Set<String> getSupportedProperties() { |
| return _broker.getSupportedProperties(); |
| } |
| |
| /** |
| * Unwraps this receiver to an instance of the given class, if possible. |
| * |
| * @exception if the given class is null, generic <code>Object.class</code> or a class |
| * that is not wrapped by this receiver. |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public <T> T unwrap(Class<T> cls) { |
| if (cls != null && cls != Object.class) { |
| Object[] delegates = new Object[] { _broker.getInnermostDelegate(), _broker.getDelegate(), _broker, this }; |
| for (Object o : delegates) { |
| if (cls.isInstance(o)) |
| return (T) o; |
| } |
| // Only call getConnection() once we are certain that is the type that we need to unwrap. |
| if (cls.isAssignableFrom(Connection.class)) { |
| Object o = getConnection(); |
| if(Connection.class.isInstance(o)){ |
| return (T) o; |
| }else{ |
| // Try and cleanup if aren't going to return the connection back to the caller. |
| ImplHelper.close(o); |
| } |
| } |
| } |
| // Set this transaction to rollback only (as per spec) here because the raised exception |
| // does not go through normal exception translation pathways |
| RuntimeException ex = new PersistenceException(_loc.get("unwrap-em-invalid", cls).toString(), null, |
| this, false); |
| if (isActive()) |
| setRollbackOnly(ex); |
| throw ex; |
| } |
| |
| @Override |
| public void setQuerySQLCache(boolean flag) { |
| _broker.setCachePreparedQuery(flag); |
| } |
| |
| @Override |
| public boolean getQuerySQLCache() { |
| return _broker.getCachePreparedQuery(); |
| } |
| |
| RuntimeExceptionTranslator getExceptionTranslator() { |
| return _ret; |
| } |
| |
| /** |
| * Populate the given FetchPlan with the given properties. |
| * Optionally overrides the given lock mode. |
| */ |
| private void configureCurrentFetchPlan(FetchPlan fetch, Map<String, Object> properties, |
| LockModeType lock, boolean requiresTxn) { |
| // handle properties in map first |
| if (properties != null) { |
| for (Map.Entry<String, Object> entry : properties.entrySet()) { |
| String key = entry.getKey(); |
| Object value = entry.getValue(); |
| if (key.equals("javax.persistence.lock.scope")) { |
| fetch.setLockScope((PessimisticLockScope)value); |
| } else |
| fetch.setHint(key, value); |
| } |
| } |
| // override with the specific lockMode, if needed. |
| if (lock != null && lock != LockModeType.NONE) { |
| if (requiresTxn) { |
| _broker.assertActiveTransaction(); |
| } |
| // Override read lock level |
| LockModeType curReadLockMode = fetch.getReadLockMode(); |
| if (lock != curReadLockMode) |
| fetch.setReadLockMode(lock); |
| } |
| } |
| |
| /** |
| * Populate the fetch configuration with specified cache mode properties. |
| * The cache mode properties modify the fetch configuration and remove those |
| * properties. This method should be called <em>before</em> the fetch configuration of the current |
| * context has been pushed. |
| * @param fetch the fetch configuration of the current context. Not the |
| * new configuration pushed (and later popped) during a single operation. |
| * |
| * @param properties |
| */ |
| private void configureCurrentCacheModes(FetchPlan fetch, Map<String, Object> properties) { |
| if (properties == null) |
| return; |
| CacheRetrieveMode rMode = JPAProperties.getEnumValue(CacheRetrieveMode.class, |
| JPAProperties.CACHE_RETRIEVE_MODE, properties); |
| if (rMode != null) { |
| fetch.setCacheRetrieveMode(JPAProperties.convertToKernelValue(DataCacheRetrieveMode.class, |
| JPAProperties.CACHE_RETRIEVE_MODE, rMode)); |
| properties.remove(JPAProperties.CACHE_RETRIEVE_MODE); |
| } |
| CacheStoreMode sMode = JPAProperties.getEnumValue(CacheStoreMode.class, |
| JPAProperties.CACHE_STORE_MODE, properties); |
| if (sMode != null) { |
| fetch.setCacheStoreMode(JPAProperties.convertToKernelValue(DataCacheStoreMode.class, |
| JPAProperties.CACHE_STORE_MODE, sMode)); |
| properties.remove(JPAProperties.CACHE_STORE_MODE); |
| } |
| } |
| |
| @Override |
| public Metamodel getMetamodel() { |
| return _emf.getMetamodel(); |
| } |
| |
| @Override |
| public <T> EntityGraph<T> createEntityGraph(Class<T> rootType) { |
| throw new UnsupportedOperationException("JPA 2.1"); |
| } |
| |
| @Override |
| public EntityGraph<?> createEntityGraph(String graphName) { |
| throw new UnsupportedOperationException("JPA 2.1"); |
| } |
| |
| @Override |
| public EntityGraph<?> getEntityGraph(String graphName) { |
| throw new UnsupportedOperationException("JPA 2.1"); |
| } |
| |
| @Override |
| public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass) { |
| throw new UnsupportedOperationException("JPA 2.1"); |
| } |
| |
| /** |
| * Sets the given property to the given value, reflectively. |
| * |
| * The property key is transposed to a bean-style property. |
| * The value is converted to a type consumable by the kernel. |
| * After requisite transformation, if the value can not be set |
| * on either this instance or its fetch plan by reflection, |
| * then an warning message (not an exception as per JPA specification) is issued. |
| */ |
| @Override |
| public void setProperty(String prop, Object value) { |
| properties = null; |
| if (!setKernelProperty(this, prop, value)) { |
| if (!setKernelProperty(this.getFetchPlan(), prop, value)) { |
| Log log = getConfiguration().getLog(OpenJPAConfiguration.LOG_RUNTIME); |
| if (log.isWarnEnabled()) { |
| log.warn(_loc.get("ignored-em-prop", prop, value == null ? "" : value.getClass()+":" + value)); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Attempt to set the given property and value to the given target instance. |
| * The original property is transposed to a bean-style property name. |
| * The original value is transformed to a type consumable by the target. |
| * |
| * @return if the property can be set to the given target. |
| */ |
| private boolean setKernelProperty(Object target, String original, Object value) { |
| String beanProp = getBeanPropertyName(original); |
| JPAProperties.record(beanProp, original); |
| Class<?> kType = null; |
| Object kValue = null; |
| Method setter = Reflection.findSetter(target.getClass(), beanProp, false); |
| if (setter != null) { |
| kType = setter.getParameterTypes()[0]; |
| kValue = convertUserValue(original, value, kType); |
| Reflection.set(target, setter, kValue); |
| return true; |
| } else { |
| Field field = Reflection.findField(target.getClass(), beanProp, false); |
| if (field != null) { |
| kType = field.getType(); |
| kValue = convertUserValue(original, value, kType); |
| Reflection.set(target, field, kValue); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Extract a bean-style property name from the given string. |
| * If the given string is <code>"a.b.xyz"</code> then returns <code>"xyz"</code> |
| */ |
| String getBeanPropertyName(String user) { |
| String result = user; |
| if (JPAProperties.isValidKey(user)) { |
| result = JPAProperties.getBeanProperty(user); |
| } else { |
| int dot = user.lastIndexOf('.'); |
| if (dot != -1) |
| result = user.substring(dot+1); |
| } |
| return result; |
| } |
| |
| |
| /** |
| * Convert the given value to a value consumable by OpenJPA kernel constructs. |
| */ |
| Object convertUserValue(String key, Object value, Class<?> targetType) { |
| if (JPAProperties.isValidKey(key)) |
| return JPAProperties.convertToKernelValue(targetType, key, value); |
| if (value instanceof String) { |
| if ("null".equals(value)) { |
| return null; |
| } else { |
| String val = (String) value; |
| int parenIndex = val.indexOf('('); |
| if (!String.class.equals(targetType) && (parenIndex > 0)) { |
| val = val.substring(0, parenIndex); |
| } |
| return StringUtil.parse(val, targetType); |
| } |
| } else if (value instanceof AutoDetachType) { |
| EnumSet<AutoDetachType> autoDetachFlags = EnumSet.noneOf(AutoDetachType.class); |
| autoDetachFlags.add((AutoDetachType)value); |
| return autoDetachFlags; |
| } else if (value instanceof AutoDetachType[]) { |
| EnumSet<AutoDetachType> autoDetachFlags = EnumSet.noneOf(AutoDetachType.class); |
| autoDetachFlags.addAll(Arrays.asList((AutoDetachType[])value)); |
| return autoDetachFlags; |
| } |
| return value; |
| } |
| |
| private Map<String, Object> cloneProperties(Map<String, Object> properties) { |
| if (properties != null) { |
| properties = new HashMap<>(properties); |
| } |
| return properties; |
| } |
| |
| private QueryMetaData getQueryMetadata(String name) { |
| MetaDataRepository repos = _broker.getConfiguration().getMetaDataRepositoryInstance(); |
| QueryMetaData meta = repos.getQueryMetaData(null, name, _broker.getClassLoader(), true); |
| if (meta == null) { |
| throw new RuntimeException("No query named [" + name + "]"); |
| } |
| return meta; |
| } |
| } |