18 package com.mysql.clusterj.openjpa;
 
   20 import java.sql.SQLException;
 
   21 import java.util.ArrayList;
 
   22 import java.util.BitSet;
 
   23 import java.util.Collection;
 
   24 import java.util.List;
 
   27 import org.apache.openjpa.jdbc.kernel.ConnectionInfo;
 
   28 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
 
   29 import org.apache.openjpa.jdbc.kernel.JDBCStoreManager;
 
   30 import org.apache.openjpa.jdbc.meta.ClassMapping;
 
   31 import org.apache.openjpa.jdbc.meta.ValueMapping;
 
   32 import org.apache.openjpa.jdbc.schema.Table;
 
   33 import org.apache.openjpa.jdbc.sql.Result;
 
   34 import org.apache.openjpa.kernel.FetchConfiguration;
 
   35 import org.apache.openjpa.kernel.OpenJPAStateManager;
 
   36 import org.apache.openjpa.kernel.PCState;
 
   37 import org.apache.openjpa.kernel.QueryLanguages;
 
   38 import org.apache.openjpa.kernel.StoreContext;
 
   39 import org.apache.openjpa.kernel.StoreQuery;
 
   40 import org.apache.openjpa.kernel.exps.ExpressionParser;
 
   41 import org.apache.openjpa.meta.ClassMetaData;
 
   42 import org.apache.openjpa.meta.FieldMetaData;
 
   43 import org.apache.openjpa.util.OpenJPAId;
 
   45 import com.mysql.clusterj.ClusterJDatastoreException;
 
   46 import com.mysql.clusterj.ClusterJException;
 
   47 import com.mysql.clusterj.ClusterJFatalInternalException;
 
   48 import com.mysql.clusterj.ClusterJFatalUserException;
 
   49 import com.mysql.clusterj.ClusterJUserException;
 
   50 import com.mysql.clusterj.SessionFactory;
 
   51 import com.mysql.clusterj.Transaction;
 
   52 import com.mysql.clusterj.core.query.QueryExecutionContextImpl;
 
   53 import com.mysql.clusterj.core.spi.DomainTypeHandler;
 
   54 import com.mysql.clusterj.core.spi.SessionSPI;
 
   55 import com.mysql.clusterj.core.spi.ValueHandler;
 
   56 import com.mysql.clusterj.core.store.Dictionary;
 
   57 import com.mysql.clusterj.core.store.Operation;
 
   58 import com.mysql.clusterj.core.store.ResultData;
 
   59 import com.mysql.clusterj.core.util.I18NHelper;
 
   60 import com.mysql.clusterj.core.util.Logger;
 
   61 import com.mysql.clusterj.core.util.LoggerFactoryService;
 
   62 import com.mysql.clusterj.query.QueryDomainType;
 
   75     @SuppressWarnings(
"unused")
 
   76     private StoreContext storeContext;
 
   90     public void setContext(StoreContext ctx) {
 
   91         super.setContext(ctx);
 
   97         ndbConfiguration = conf;
 
   98         sessionFactory = conf.getSessionFactory();
 
  102     protected NdbOpenJPADomainTypeHandlerImpl<?> getDomainTypeHandler(OpenJPAStateManager sm) {
 
  104         ClassMapping cmp = (ClassMapping) sm.getMetaData();
 
  105         return getDomainTypeHandler(cmp);
 
  108     protected NdbOpenJPADomainTypeHandlerImpl<?> getDomainTypeHandler(ClassMapping cmp) {
 
  109         NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler =
 
  110             ndbConfiguration.getDomainTypeHandler(cmp, dictionary);
 
  111         return domainTypeHandler;
 
  114     protected int deleteAll(DomainTypeHandler<?> base) {
 
  116         int result = session.deletePersistentAll(base);
 
  121         if (session == null) {
 
  123             dictionary = session.getDictionary();
 
  131     public Object 
find(Object oid, ValueMapping vm,
 
  132         JDBCFetchConfiguration fetch) {
 
  133         if (logger.isDebugEnabled()) {
 
  134             logger.debug(
"NdbStoreManager.find(Object oid, ValueMapping vm, " 
  135                     + 
"JDBCFetchConfiguration fetch) delegated to super with oid " + oid + 
".");
 
  138         ClassMapping cls = vm.getDeclaredTypeMapping();
 
  139         NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = getDomainTypeHandler(cls);
 
  140         Object 
handler = domainTypeHandler.createKeyValueHandler(oid);
 
  141         if (handler == null) {
 
  144         return super.find(oid, vm, fetch);
 
  156     public boolean load(OpenJPAStateManager sm, BitSet fields,
 
  157             FetchConfiguration fetch, 
int lockLevel, Object context) {
 
  158         if (logger.isDebugEnabled()) {
 
  159             logger.debug(
"NdbStoreManager.load(OpenJPAStateManager sm, BitSet fields, " 
  160                     + 
"FetchConfiguration fetch, int lockLevel, Object context) " 
  161                     + 
"Id: " + sm.getId() + 
" requested fields: " 
  164         if (context != null && ((ConnectionInfo) context).result != null) {
 
  166             return super.load(sm, fields, fetch, lockLevel, context);
 
  168             NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = getDomainTypeHandler(sm);
 
  169             if (!isSupportedType(domainTypeHandler, 
"NdbOpenJPAStoreManager.load")) {
 
  170                 return super.load(sm, fields, fetch, lockLevel, context);
 
  173                     return domainTypeHandler.load(sm, 
this, fields, (JDBCFetchConfiguration) fetch, context);
 
  174                 } 
catch (SQLException sQLException) {
 
  175                     logger.error(
"Fatal error from NdbOpenJPAStoreManager.load " + sQLException);
 
  183     public Object 
load(ClassMapping mapping, JDBCFetchConfiguration fetch,
 
  184         BitSet exclude, Result result) 
throws SQLException {
 
  185         if (logger.isDebugEnabled()) {
 
  186             logger.debug(
"NdbStoreManager.load(ClassMapping mapping, JDBCFetchConfiguration fetch, " 
  187                     + 
"BitSet exclude, Result result) for " +  mapping.getDescribedType().getName()
 
  188                     + 
" delegated to super.");
 
  190         return super.load(mapping, fetch, exclude, result);
 
  193     @SuppressWarnings(
"unchecked")
 
  195     public Collection loadAll(Collection sms, PCState state, 
int load,
 
  196         FetchConfiguration fetch, Object context) {
 
  197         if (logger.isDebugEnabled()) {
 
  198             logger.debug(
"NdbStoreManager.loadAll(Collection sms, PCState state, int load, " 
  199                     + 
"FetchConfiguration fetch, Object context) delegated to super.");
 
  201         return super.loadAll(sms, state, load, fetch, context);
 
  205     public boolean initialize(OpenJPAStateManager sm, PCState state,
 
  206         FetchConfiguration fetch, Object context) {
 
  207         if (logger.isDebugEnabled()) {
 
  208             logger.debug(
"NdbStoreManager.initialize(OpenJPAStateManager sm, PCState state, " 
  209                     + 
"FetchConfiguration fetch, Object context)");
 
  212         if (context != null) {
 
  213             ConnectionInfo info = (ConnectionInfo)context;
 
  214             ClassMapping mapping = info.mapping;
 
  215             Result result = info.result;
 
  216             logger.info(
"info mapping: " + mapping.getDescribedType().getName() + 
" result: " + result);
 
  218                 return initializeState(sm, state, (JDBCFetchConfiguration)fetch, info);
 
  219             } 
catch (ClassNotFoundException e) {
 
  220                 throw new ClusterJFatalInternalException(local.
message(
"ERR_Implementation_Should_Not_Occur"), e);
 
  221             } 
catch (SQLException e) {
 
  222                 throw new ClusterJDatastoreException(local.
message(
"ERR_Datastore_Exception"), e);
 
  227         OpenJPAId 
id = (OpenJPAId)sm.getId();
 
  228         if (logger.isTraceEnabled()) {
 
  229             logger.trace(
"Id: " + 
id.getClass() + 
" " + 
id);
 
  232         NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = getDomainTypeHandler(sm);
 
  234         if (!isSupportedType(domainTypeHandler, 
"NdbOpenJPAStoreManager.initialize")) {
 
  236             boolean result = super.initialize(sm, state, fetch, context);
 
  237             if (logger.isDebugEnabled()) logger.debug(
 
  238                     "NdbOpenJPAStoreManager.initialize delegated to super: returned " + result);
 
  244             session.startAutoTransaction();
 
  254                 ValueHandler keyValueHandler = domainTypeHandler.createKeyValueHandler(
id.getIdObject());
 
  255                 ResultData resultData = session.selectUnique(domainTypeHandler,
 
  259                 NdbOpenJPAResult result = 
new NdbOpenJPAResult(resultData, domainTypeHandler, null);
 
  262                     domainTypeHandler.newInstance(sm);
 
  267                     domainTypeHandler.load(sm, 
this, (JDBCFetchConfiguration)fetch, result);
 
  278             if (logger.isDetailEnabled()) {
 
  279                 logger.detail(
"After initializing PCState: " +
 
  280                         sm.getPCState().getClass().getSimpleName() + 
" " +
 
  283             session.endAutoTransaction();
 
  286         } 
catch (ClusterJException e) {
 
  287             session.failAutoTransaction();
 
  289         } 
catch (Exception e) {
 
  290             session.failAutoTransaction();
 
  291             throw new ClusterJFatalInternalException(
"Unexpected exception.", e);
 
  298     protected boolean initializeState(OpenJPAStateManager sm, PCState state,
 
  299             JDBCFetchConfiguration fetch, ConnectionInfo info)
 
  300             throws ClassNotFoundException, SQLException {
 
  301         if (logger.isDebugEnabled()) {
 
  302             logger.debug(
"NdbStoreManager.initializeState(" +
 
  303                     "OpenJPAStateManager, PCState, JDBCFetchConfiguration, " +
 
  304                     "ConnectionInfo) delegated to super.");
 
  306         return super.initializeState(sm, state, fetch, info);
 
  325     @SuppressWarnings(
"unchecked")
 
  327     public Collection<Exception> 
flush(Collection sms) {
 
  328         Collection<OpenJPAStateManager> stateManagers =
 
  329                 (Collection<OpenJPAStateManager>)sms;
 
  331         if (logger.isTraceEnabled()) {
 
  335         boolean allSupportedTypes = 
true;
 
  336         for (OpenJPAStateManager sm: stateManagers) {
 
  337             DomainTypeHandler<?> domainTypeHandler = getDomainTypeHandler(sm);
 
  338             if (!domainTypeHandler.isSupportedType()) {
 
  339                 if (logger.isDetailEnabled()) logger.detail(
"Found unsupported class " 
  340                         + domainTypeHandler.getName());
 
  341                 if (ndbConfiguration.getFailOnJDBCPath()) {
 
  343                             local.
message(
"ERR_JDBC_Path", domainTypeHandler.getName()));
 
  345                 allSupportedTypes = 
false;
 
  347             if (logger.isTraceEnabled()) {
 
  348                 buffer.append(printState(sm));
 
  351         if (logger.isTraceEnabled()) {
 
  352                 logger.trace(buffer.toString());
 
  354         if (!allSupportedTypes) {
 
  356             Collection<Exception> exceptions = super.flush(sms);
 
  357             if (logger.isDetailEnabled()) logger.detail(
"Found unsupported class(es); " 
  358                     + 
"super resulted in exceptions: " + exceptions);
 
  363         Collection exceptions = 
new ArrayList<Exception>();
 
  364         for (OpenJPAStateManager sm:stateManagers) {
 
  366             NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler = getDomainTypeHandler(sm);
 
  368             ValueHandler valueHandler = domainTypeHandler.getValueHandler(sm, 
this);
 
  370             PCState pcState = sm.getPCState();
 
  372                 if (pcState == PCState.PNEW) {
 
  374                     session.insert(domainTypeHandler, valueHandler);
 
  375                 } 
else if (pcState == PCState.PDELETED) {
 
  377                     session.delete(domainTypeHandler, valueHandler);
 
  378                 } 
else if (pcState == PCState.PDIRTY) {
 
  380                     session.update(domainTypeHandler, valueHandler);
 
  381                 } 
else if (pcState == PCState.PNEWFLUSHEDDELETED) {
 
  383                     session.delete(domainTypeHandler, valueHandler);
 
  384                 } 
else if (pcState == PCState.PNEWFLUSHEDDELETEDFLUSHED) {
 
  388                             local.
message(
"ERR_Unsupported_Flush_Operation",
 
  389                             pcState.toString()));
 
  391             } 
catch (Exception ex) {
 
  392                 if (logger.isDebugEnabled()) {
 
  393                     logger.debug(
"Exception caught: " + ex.toString());
 
  409     private boolean isSupportedType(NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler,
 
  411         boolean result = domainTypeHandler.isSupportedType();
 
  413             if (logger.isDebugEnabled()) logger.debug(where 
 
  414                     + 
" found unsupported class " + domainTypeHandler.getName());
 
  415             if (ndbConfiguration.getFailOnJDBCPath()) {
 
  417                         local.
message(
"ERR_JDBC_Path", domainTypeHandler.getName()));
 
  424     public void beforeStateChange(OpenJPAStateManager sm, PCState fromState,
 
  426         if (logger.isDetailEnabled()) {
 
  428                 printState(
"from ", fromState) +
 
  429                 printState(
" to ", toState));
 
  431         super.beforeStateChange(sm, fromState, toState);
 
  435     public StoreQuery newQuery(
String language) {
 
  436         ExpressionParser ep = QueryLanguages.parserForLanguage(language);
 
  437         return new NdbOpenJPAStoreQuery(
this, ep);
 
  441     public void beginOptimistic() {
 
  442         if (logger.isTraceEnabled()) {
 
  443             logger.trace(
" Transaction " + hashCode() + printIsActive(tx));
 
  445         super.beginOptimistic();
 
  453         } 
catch (Exception e) {
 
  454             logger.detail(
"NdbOpenJPAStoreManager.beginOptimistic():" +
 
  455                     "caught exception in session.currentTransaction.begin().");
 
  456             throw new ClusterJDatastoreException(
 
  457                     local.
message(
"ERR_Datastore_Exception"), e);
 
  462     public void begin() {
 
  463         if (logger.isTraceEnabled()) {logger.trace(
" Transaction " + hashCode() + printIsActive(tx));}
 
  472         } 
catch (Exception e) {
 
  473             logger.detail(
"Caught exception in session.currentTransaction.commit()." +
 
  481     public void commit() {
 
  482         if (logger.isTraceEnabled()) {logger.trace(
" Transaction " + hashCode() + printIsActive(tx));}
 
  485         } 
catch (Exception ex) {
 
  486             logger.detail(
" failed" + ex.toString());
 
  487             throw new ClusterJException(
 
  488                     local.
message(
"ERR_Commit_Failed", ex.toString()));
 
  495     public void rollback() {
 
  496         if (logger.isTraceEnabled()) {logger.trace(
" Transaction " + hashCode() + printIsActive(tx));}
 
  503     public void close() {
 
  504         if (logger.isTraceEnabled()) {logger.trace(
" Transaction " + hashCode() + printIsActive(tx));}
 
  505         if (session != null && !session.
isClosed()) {
 
  513     protected String printState(OpenJPAStateManager sm) {
 
  515         buffer.append(
"class: ");
 
  516         buffer.append(sm.getPersistenceCapable().getClass().getName());
 
  517         buffer.append(
" objectId: ");
 
  518         buffer.append(sm.getObjectId());
 
  519         buffer.append(
" PCState: ");
 
  520         buffer.append(sm.getPCState());
 
  522         return buffer.toString();
 
  525     protected String printState(
String header, PCState state) {
 
  527         buffer.append(state.getClass().getSimpleName());
 
  528         return buffer.toString();
 
  531     protected String printLoaded(OpenJPAStateManager sm) {
 
  532         BitSet loaded = sm.getLoaded();
 
  533         return "Loaded: " + NdbOpenJPAUtility.printBitSet(sm, loaded);
 
  536     protected String printIsActive(Transaction tx) {
 
  537         return (tx==null?
" is null.":tx.isActive()?
" is active.":
" is not active.");
 
  556     public <T> QueryDomainType<T> createQueryDomainType(Class<T> 
type) {
 
  567             QueryDomainType<?> queryDomainType, Map<String, Object> parameterMap) {
 
  569         ResultData resultData = context.getResultData(queryDomainType);
 
  581             NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler, 
 
  582             List<NdbOpenJPADomainFieldHandlerImpl> fieldHandlers) {
 
  583         com.mysql.clusterj.core.store.Table storeTable = domainTypeHandler.getStoreTable();
 
  584         session.startAutoTransaction();
 
  586             Operation op = session.getSelectOperation(storeTable);
 
  587             int[] keyFields = domainTypeHandler.getKeyFieldNumbers();
 
  588             BitSet fieldsInResult = 
new BitSet();
 
  589             for (
int i : keyFields) {
 
  590                 fieldsInResult.set(
i);
 
  593             domainTypeHandler.operationSetKeys(handler, op);
 
  595             domainTypeHandler.operationGetKeys(op);
 
  597                 fieldHandler.operationGetValue(op);
 
  598                 fieldsInResult.set(fieldHandler.getFieldNumber());
 
  602             session.endAutoTransaction();
 
  604         } 
catch (RuntimeException ex) {
 
  605             session.failAutoTransaction();