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();