*
* Use a no-wait transaction to avoid blocking on a Replica while
* attempting to open an index that is currently being populated
* via the replication stream from the Master.
*/
Transaction txn = null;
DatabaseConfig dbConfig = getPrimaryConfig(entityMeta);
if (dbConfig.getTransactional() &&
DbCompat.getThreadTransaction(env) == null) {
txn = env.beginTransaction(null, autoCommitNoWaitTxnConfig);
}
PrimaryOpenState priOpenState =
new PrimaryOpenState(entityClassName);
final boolean saveAllowCreate = dbConfig.getAllowCreate();
boolean success = false;
try {
/*
* The AllowCreate setting is false in read-only / Replica
* upgrade mode. In this mode new primaries are not available.
* They can be opened later when the upgrade is complete on the
* Master, by calling getSecondaryIndex. [#16655]
*/
if (catalog.isReadOnly()) {
dbConfig.setAllowCreate(false);
}
/*
* Open the primary database. Account for database renaming
* by calling getDatabaseClassName. The dbClassName will be
* null if the format has not yet been stored. [#16655].
*/
Database db = null;
final String dbClassName =
catalog.getDatabaseClassName(entityClassName);
if (dbClassName != null) {
final String[] fileAndDbNames =
parseDbName(storePrefix + dbClassName);
/* <!-- begin JE only --> */
try {
/* <!-- end JE only --> */
db = DbCompat.openDatabase(env, txn, fileAndDbNames[0],
fileAndDbNames[1],
dbConfig);
/* <!-- begin JE only --> */
} catch (LockConflictException e) {
/* Treat this as if the database does not exist. */
}
/* <!-- end JE only --> */
}
if (db == null) {
throw new IndexNotAvailableException
("PrimaryIndex not yet available on this Replica, " +
"entity class: " + entityClassName);
}
priOpenState.addDatabase(db);
/* Create index object. */
priIndex = new InternalPrimaryIndex(db, primaryKeyClass,
keyBinding, entityClass,
entityBinding);
/* Update index and database maps. */
priIndexMap.put(entityClassName, priIndex);
if (DbCompat.getDeferredWrite(dbConfig)) {
deferredWriteDatabases.put(db, null);
}
/* If not read-only, open all associated secondaries. */
if (!dbConfig.getReadOnly()) {
openSecondaryIndexes(txn, entityMeta, priOpenState);
/*
* To enable foreign key contraints, also open all primary
* indexes referring to this class via a relatedEntity
* property in another entity. [#15358]
*/
Set<String> inverseClassNames =
inverseRelatedEntityMap.get(entityClassName);
if (inverseClassNames != null) {
for (String relatedClsName : inverseClassNames) {
getRelatedIndex(relatedClsName);
}
}
}
success = true;
} finally {
dbConfig.setAllowCreate(saveAllowCreate);
if (success) {
if (txn != null) {
txn.commit();
}
} else {
if (txn != null) {
txn.abort();
}
priOpenState.undoState();
}
}
}