/** * Opens a primary index related via a foreign key (relatedEntity). Related indexes are not opened * in the same transaction used by the caller to open a primary or secondary. It is OK to leave * the related index open when the caller's transaction aborts. It is only important to open a * primary and its secondaries atomically. */ private PrimaryIndex getRelatedIndex(String relatedClsName) throws DatabaseException { PrimaryIndex relatedIndex = priIndexMap.get(relatedClsName); if (relatedIndex == null) { EntityMetadata relatedEntityMeta = checkEntityClass(relatedClsName); Class relatedKeyCls; String relatedKeyClsName; Class relatedCls; if (rawAccess) { relatedCls = RawObject.class; relatedKeyCls = Object.class; relatedKeyClsName = null; } else { try { relatedCls = EntityModel.classForName(relatedClsName); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Related entity class not found: " + relatedClsName); } relatedKeyClsName = SimpleCatalog.keyClassName(relatedEntityMeta.getPrimaryKey().getClassName()); relatedKeyCls = SimpleCatalog.keyClassForName(relatedKeyClsName); } /* * Cycles are prevented here by adding primary indexes to the * priIndexMap as soon as they are created, before opening related * indexes. */ relatedIndex = getPrimaryIndex( relatedKeyCls, relatedKeyClsName, relatedCls, relatedClsName); } return relatedIndex; }
/** * Opens any secondary indexes defined in the given entity metadata that are not already open. * This method is called when a new entity subclass is encountered when an instance of that class * is stored, and the EntityStore.getSubclassIndex has not been previously called for that class. * [#15247] */ synchronized void openSecondaryIndexes( Transaction txn, EntityMetadata entityMeta, PrimaryOpenState priOpenState) throws DatabaseException { String entityClassName = entityMeta.getClassName(); PrimaryIndex<Object, Object> priIndex = priIndexMap.get(entityClassName); assert priIndex != null; Class<Object> entityClass = priIndex.getEntityClass(); for (SecondaryKeyMetadata secKeyMeta : entityMeta.getSecondaryKeys().values()) { String keyName = secKeyMeta.getKeyName(); String secName = makeSecName(entityClassName, keyName); SecondaryIndex<Object, Object, Object> secIndex = secIndexMap.get(secName); if (secIndex == null) { String keyClassName = getSecKeyClass(secKeyMeta); /* RawMode: should not require class. */ Class keyClass = SimpleCatalog.keyClassForName(keyClassName); openSecondaryIndex( txn, priIndex, entityClass, entityMeta, keyClass, keyClassName, secKeyMeta, makeSecName(entityClassName, secKeyMeta.getKeyName()), storeConfig.getSecondaryBulkLoad() /*doNotCreate*/, priOpenState); } } }
private void setBtreeComparator(DatabaseConfig config, String clsName) { if (!rawAccess) { ClassMetadata meta = model.getClassMetadata(clsName); if (meta != null) { List<FieldMetadata> compositeKeyFields = meta.getCompositeKeyFields(); if (compositeKeyFields != null) { Class keyClass = SimpleCatalog.keyClassForName(clsName); if (Comparable.class.isAssignableFrom(keyClass)) { Comparator<Object> cmp = new PersistComparator(clsName, compositeKeyFields, getKeyBinding(clsName)); config.setBtreeComparator(cmp); } } } } }