public boolean setup(boolean readOnly) {
      boolean open = false;
      try {
        EnvironmentConfig envConfig = new EnvironmentConfig();
        envConfig.setReadOnly(readOnly);
        envConfig.setAllowCreate(!readOnly);

        env = new Environment(envHome, envConfig);

        StoreConfig storeConfig = new StoreConfig();
        storeConfig.setReadOnly(readOnly);
        storeConfig.setAllowCreate(!readOnly);

        store = new EntityStore(env, "EntityStore", storeConfig);

        objectBySid = store.getPrimaryIndex(String.class, TestObject.class);

        open = true;
      } catch (EnvironmentLockedException e) {
      } catch (Exception e) {
        e.printStackTrace();
        System.exit(-1);
      }

      return open;
    }
  /**
   * Returns true if the store was opened successfully. Returns false if the store could not be
   * opened because an exception was expected -- this is not a test failure but no further tests for
   * an EntityStore may be run.
   */
  private boolean openStore(StoreConfig config) throws Exception {

    config.setTransactional(true);
    config.setMutations(caseObj.getMutations());

    EntityModel model = new AnnotationModel();
    config.setModel(model);
    caseObj.configure(model, config);

    String expectException = caseObj.getStoreOpenException();
    try {
      store = new EntityStore(env, EvolveCase.STORE_NAME, config);
      if (expectException != null) {
        fail("Expected: " + expectException);
      }
    } catch (Exception e) {
      if (expectException != null) {
        String actualMsg = e.getMessage();
        if (e instanceof IncompatibleClassException) {
          actualMsg = actualMsg.substring(0, actualMsg.lastIndexOf("\n---\n(Note that"));
        }
        actualMsg = e.getClass().getName() + ": " + actualMsg;
        if (!expectException.equals(actualMsg)) {
          e.printStackTrace();
        }
        EvolveCase.checkEquals(expectException, actualMsg);
        return false;
      } else {
        throw e;
      }
    }
    return true;
  }
Beispiel #3
0
  private void open() throws DatabaseException {

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(envConfig.getAllowCreate());
    config.setTransactional(envConfig.getTransactional());

    store = new EntityStore(env, "test", config);
  }
  boolean openStoreReadWrite() throws Exception {

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    final boolean retVal = openStore(config);
    if (retVal) {
      caseObj.newMetadataWritten = true;
    }
    return retVal;
  }
Beispiel #5
0
  private void open(Class clsToRegister) throws DatabaseException {

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(envConfig.getAllowCreate());
    if (clsToRegister != null) {
      com.sleepycat.persist.model.EntityModel model =
          new com.sleepycat.persist.model.AnnotationModel();
      model.registerClass(clsToRegister);
      config.setModel(model);
    }
    open(config);
  }
  /** Create all primary and secondary indices. */
  private void init() throws DatabaseException {

    /* Open a transactional entity store. */
    System.out.println("-> Creating a BDB database");
    StoreConfig storeConfig = new StoreConfig();
    storeConfig.setAllowCreate(true);
    storeConfig.setTransactional(true);
    store = new EntityStore(env, "ExampleStore", storeConfig);

    eventByTime = store.getPrimaryIndex(Date.class, Event.class);
    eventByPrice = store.getSecondaryIndex(eventByTime, Integer.class, "price");
  }
  void openNewStore() throws Exception {

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    config.setTransactional(true);

    EntityModel model = new AnnotationModel();
    config.setModel(model);
    caseObj.configure(model, config);

    newStore = new EntityStore(env, "new", config);
  }
Beispiel #8
0
 private synchronized DatabaseConfig getPrimaryConfig(EntityMetadata meta) {
   String clsName = meta.getClassName();
   DatabaseConfig config = priConfigMap.get(clsName);
   if (config == null) {
     config = new DatabaseConfig();
     config.setTransactional(storeConfig.getTransactional());
     config.setAllowCreate(!storeConfig.getReadOnly());
     config.setReadOnly(storeConfig.getReadOnly());
     DbCompat.setDeferredWrite(config, storeConfig.getDeferredWrite());
     setBtreeComparator(config, meta.getPrimaryKey().getClassName());
     priConfigMap.put(clsName, config);
   }
   return config;
 }
Beispiel #9
0
  /**
   * When opening read-only, secondaries are not opened when the primary is opened, causing a
   * different code path to be used for opening secondaries. For a RawStore in particular, this
   * caused an unreported NullPointerException in JE 3.0.12. No SR was created because the use case
   * is very obscure and was discovered by code inspection.
   */
  public void testOpenRawStoreReadOnly() throws DatabaseException {

    open();
    store.getPrimaryIndex(Integer.class, MyEntity.class);
    close();

    StoreConfig config = new StoreConfig();
    config.setReadOnly(true);
    config.setTransactional(envConfig.getTransactional());
    RawStore rawStore = new RawStore(env, "test", config);

    String clsName = MyEntity.class.getName();
    rawStore.getSecondaryIndex(clsName, "secKey");

    rawStore.close();
  }
Beispiel #10
0
  /**
   * 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 openGroup() throws IOException {

    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setTransactional(true);
    envConfig.setAllowCreate(true);

    ReplicationConfig repConfig = new ReplicationConfig();
    repConfig.setConfigParam(RepParams.VLSN_LOG_CACHE_SIZE.getName(), "2");

    repEnvInfo = RepTestUtils.setupEnvInfos(envRoot, nNodes, envConfig, repConfig);
    master = RepTestUtils.joinGroup(repEnvInfo);

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    config.setTransactional(true);
    store = new EntityStore(master, "test", config);
    primaryIndex = store.getPrimaryIndex(Integer.class, AppData.class);
  }
Beispiel #12
0
 public synchronized SequenceConfig getSequenceConfig(String name) {
   checkOpen();
   SequenceConfig config = sequenceConfigMap.get(name);
   if (config == null) {
     config = new SequenceConfig();
     config.setInitialValue(1);
     config.setRange(1, Long.MAX_VALUE);
     config.setCacheSize(100);
     config.setAutoCommitNoSync(true);
     config.setAllowCreate(!storeConfig.getReadOnly());
     sequenceConfigMap.put(name, config);
   }
   return config;
 }
  /** Opens the store. */
  private void open() throws DatabaseException {

    StoreConfig config = new StoreConfig();
    config.setAllowCreate(envConfig.getAllowCreate());
    config.setTransactional(envConfig.getTransactional());

    store = new EntityStore(env, "test", config);

    primary = store.getPrimaryIndex(Integer.class, MyEntity.class);
    oneToOne = store.getSecondaryIndex(primary, Integer.class, "oneToOne");
    manyToOne = store.getSecondaryIndex(primary, Integer.class, "manyToOne");
    oneToMany = store.getSecondaryIndex(primary, Integer.class, "oneToMany");
    manyToMany = store.getSecondaryIndex(primary, Integer.class, "manyToMany");

    assertNotNull(primary);
    assertNotNull(oneToOne);
    assertNotNull(manyToOne);
    assertNotNull(oneToMany);
    assertNotNull(manyToMany);

    rawStore = new RawStore(env, "test", config);
    String clsName = MyEntity.class.getName();
    entityType = rawStore.getModel().getRawType(clsName);
    assertNotNull(entityType);

    primaryRaw = rawStore.getPrimaryIndex(clsName);
    oneToOneRaw = rawStore.getSecondaryIndex(clsName, "oneToOne");
    manyToOneRaw = rawStore.getSecondaryIndex(clsName, "manyToOne");
    oneToManyRaw = rawStore.getSecondaryIndex(clsName, "oneToMany");
    manyToManyRaw = rawStore.getSecondaryIndex(clsName, "manyToMany");

    assertNotNull(primaryRaw);
    assertNotNull(oneToOneRaw);
    assertNotNull(manyToOneRaw);
    assertNotNull(oneToManyRaw);
    assertNotNull(manyToManyRaw);
  }
Beispiel #14
0
  public synchronized Sequence getSequence(String name) throws DatabaseException {

    checkOpen();

    if (storeConfig.getReadOnly()) {
      throw new IllegalStateException("Store is read-only");
    }

    Sequence seq = sequenceMap.get(name);
    if (seq == null) {
      if (sequenceDb == null) {
        String dbName = storePrefix + SEQUENCE_DB;
        DatabaseConfig dbConfig = new DatabaseConfig();
        dbConfig.setTransactional(storeConfig.getTransactional());
        dbConfig.setAllowCreate(true);
        sequenceDb = env.openDatabase(null, dbName, dbConfig);
      }
      DatabaseEntry entry = new DatabaseEntry();
      StringBinding.stringToEntry(name, entry);
      seq = sequenceDb.openSequence(null, entry, getSequenceConfig(name));
      sequenceMap.put(name, seq);
    }
    return seq;
  }
  /**
   * Load the index data from the input file and transfer it to the persistent hash table
   *
   * @param dbDir
   */
  public void setup(File dbDir) {
    try {
      // Setup needed classes for interacting with Berkeley DNB Java Edition
      EnvironmentConfig envConfig = new EnvironmentConfig();
      StoreConfig storeConfig = new StoreConfig();
      envConfig.setAllowCreate(true);
      // Try to keep a high amount of data in the cache.
      envConfig.setCachePercent(80);
      storeConfig.setAllowCreate(true);
      this.myDbEnvironment = new Environment(dbDir, envConfig);
      this.dictStore = new EntityStore(myDbEnvironment, "EntityStore", storeConfig);
      this.pidx = dictStore.getPrimaryIndex(String.class, KeyValueEntry.class);

      if (this.pidx.count() == 0) {
        // prep the index
        try {
          BufferedReader reader = new BufferedReader(new FileReader(this.indexFile));
          String line = null;
          while ((line = reader.readLine()) != null) {
            // de-serialize object from input file
            KeyValueEntry kvp = KeyValueEntry.fromString(line);
            // store in persistent hash table
            this.pidx.put(kvp);
          }
          reader.close();
        } catch (IOException ioe) {
          ioe.printStackTrace();
        }
      }

    } catch (DatabaseException dbe) {
      this.myDbEnvironment = null;
      this.dictStore = null;
      this.pidx = null;
    }
  }
Beispiel #16
0
  public Store(Environment env, String storeName, StoreConfig config, boolean rawAccess)
      throws DatabaseException {

    this.env = env;
    this.storeName = storeName;
    this.rawAccess = rawAccess;

    if (env == null || storeName == null) {
      throw new NullPointerException("env and storeName parameters must not be null");
    }
    if (config != null) {
      model = config.getModel();
      mutations = config.getMutations();
    }
    if (config == null) {
      storeConfig = StoreConfig.DEFAULT;
    } else {
      storeConfig = config.cloneConfig();
    }

    storePrefix = NAME_PREFIX + storeName + NAME_SEPARATOR;
    priIndexMap = new HashMap<String, PrimaryIndex>();
    secIndexMap = new HashMap<String, SecondaryIndex>();
    priConfigMap = new HashMap<String, DatabaseConfig>();
    secConfigMap = new HashMap<String, SecondaryConfig>();
    keyBindingMap = new HashMap<String, PersistKeyBinding>();
    sequenceMap = new HashMap<String, Sequence>();
    sequenceConfigMap = new HashMap<String, SequenceConfig>();
    deferredWriteDatabases = new IdentityHashMap<Database, Object>();

    if (rawAccess) {
      /* Open a read-only catalog that uses the stored model. */
      if (model != null) {
        throw new IllegalArgumentException("A model may not be specified when opening a RawStore");
      }
      DatabaseConfig dbConfig = new DatabaseConfig();
      dbConfig.setReadOnly(true);
      dbConfig.setTransactional(storeConfig.getTransactional());
      catalog =
          new PersistCatalog(
              null,
              env,
              storePrefix,
              storePrefix + CATALOG_DB,
              dbConfig,
              model,
              mutations,
              rawAccess,
              this);
    } else {
      /* Open the shared catalog that uses the current model. */
      synchronized (catalogPool) {
        Map<String, PersistCatalog> catalogMap = catalogPool.get(env);
        if (catalogMap == null) {
          catalogMap = new HashMap<String, PersistCatalog>();
          catalogPool.put(env, catalogMap);
        }
        catalog = catalogMap.get(storeName);
        if (catalog != null) {
          catalog.openExisting();
        } else {
          Transaction txn = null;
          if (storeConfig.getTransactional() && env.getThreadTransaction() == null) {
            txn = env.beginTransaction(null, null);
          }
          boolean success = false;
          try {
            DatabaseConfig dbConfig = new DatabaseConfig();
            dbConfig.setAllowCreate(storeConfig.getAllowCreate());
            dbConfig.setReadOnly(storeConfig.getReadOnly());
            dbConfig.setTransactional(storeConfig.getTransactional());
            catalog =
                new PersistCatalog(
                    txn,
                    env,
                    storePrefix,
                    storePrefix + CATALOG_DB,
                    dbConfig,
                    model,
                    mutations,
                    rawAccess,
                    this);
            catalogMap.put(storeName, catalog);
            success = true;
          } finally {
            if (txn != null) {
              if (success) {
                txn.commit();
              } else {
                txn.abort();
              }
            }
          }
        }
      }
    }

    /* Get the merged mutations from the catalog. */
    mutations = catalog.getMutations();

    /*
     * If there is no model parameter, use the default or stored model
     * obtained from the catalog.
     */
    model = catalog.getResolvedModel();

    /*
     * Give the model a reference to the catalog to fully initialize the
     * model.  Only then may we initialize the Converter mutations, which
     * themselves may call model methods and expect the model to be fully
     * initialized.
     */
    ModelInternal.setCatalog(model, catalog);
    for (Converter converter : mutations.getConverters()) {
      converter.getConversion().initialize(model);
    }

    /*
     * For each existing entity with a relatedEntity reference, create an
     * inverse map (back pointer) from the class named in the relatedEntity
     * to the class containing the secondary key.  This is used to open the
     * class containing the secondary key whenever we open the
     * relatedEntity class, to configure foreign key constraints. Note that
     * we do not need to update this map as new primary indexes are
     * created, because opening the new index will setup the foreign key
     * constraints. [#15358]
     */
    inverseRelatedEntityMap = new HashMap<String, Set<String>>();
    List<Format> entityFormats = new ArrayList<Format>();
    catalog.getEntityFormats(entityFormats);
    for (Format entityFormat : entityFormats) {
      EntityMetadata entityMeta = entityFormat.getEntityMetadata();
      for (SecondaryKeyMetadata secKeyMeta : entityMeta.getSecondaryKeys().values()) {
        String relatedClsName = secKeyMeta.getRelatedEntity();
        if (relatedClsName != null) {
          Set<String> inverseClassNames = inverseRelatedEntityMap.get(relatedClsName);
          if (inverseClassNames == null) {
            inverseClassNames = new HashSet<String>();
            inverseRelatedEntityMap.put(relatedClsName, inverseClassNames);
          }
          inverseClassNames.add(entityMeta.getClassName());
        }
      }
    }
  }
Beispiel #17
0
 public StoreConfig getConfig() {
   return storeConfig.cloneConfig();
 }
Beispiel #18
0
  public void testSubclassIndex() throws DatabaseException {

    EnvironmentConfig envConfig = new EnvironmentConfig();
    envConfig.setAllowCreate(true);
    env = new Environment(envHome, envConfig);

    StoreConfig storeConfig = new StoreConfig();
    storeConfig.setAllowCreate(true);
    EntityStore store = new EntityStore(env, "foo", storeConfig);

    PrimaryIndex<String, Employee> employeesById =
        store.getPrimaryIndex(String.class, Employee.class);

    employeesById.put(new Employee("1"));
    employeesById.put(new Manager("2", "a"));
    employeesById.put(new Manager("3", "a"));
    employeesById.put(new Manager("4", "b"));

    Employee e;
    Manager m;

    e = employeesById.get("1");
    assertNotNull(e);
    assertTrue(!(e instanceof Manager));

    /* Ensure DB exists BEFORE calling getSubclassIndex. [#15247] */
    PersistTestUtils.assertDbExists(true, env, "foo", Employee.class.getName(), "dept");

    /* Normal use: Subclass index for a key in the subclass. */
    SecondaryIndex<String, String, Manager> managersByDept =
        store.getSubclassIndex(employeesById, Manager.class, String.class, "dept");

    m = managersByDept.get("a");
    assertNotNull(m);
    assertEquals("2", m.id);

    m = managersByDept.get("b");
    assertNotNull(m);
    assertEquals("4", m.id);

    EntityCursor<Manager> managers = managersByDept.entities();
    try {
      m = managers.next();
      assertNotNull(m);
      assertEquals("2", m.id);
      m = managers.next();
      assertNotNull(m);
      assertEquals("3", m.id);
      m = managers.next();
      assertNotNull(m);
      assertEquals("4", m.id);
      m = managers.next();
      assertNull(m);
    } finally {
      managers.close();
    }

    /* Getting a subclass index for the entity class is also allowed. */
    store.getSubclassIndex(employeesById, Employee.class, String.class, "other");

    /* Getting a subclass index for a base class key is not allowed. */
    try {
      store.getSubclassIndex(employeesById, Manager.class, String.class, "other");
      fail();
    } catch (IllegalArgumentException expected) {
    }

    store.close();
    env.close();
    env = null;
  }
  void openRawStore() throws DatabaseException {

    StoreConfig config = new StoreConfig();
    config.setTransactional(true);
    rawStore = new RawStore(env, EvolveCase.STORE_NAME, config);
  }
  boolean openStoreReadOnly() throws Exception {

    StoreConfig config = new StoreConfig();
    config.setReadOnly(true);
    return openStore(config);
  }
Beispiel #21
0
  private void openReadOnly() throws DatabaseException {

    StoreConfig config = new StoreConfig();
    config.setReadOnly(true);
    open(config);
  }
Beispiel #22
0
  /**
   * A getPrimaryIndex with extra parameters for opening a raw store. primaryKeyClass and
   * entityClass are used for generic typing; for a raw store, these should always be Object.class
   * and RawObject.class. primaryKeyClassName is used for consistency checking and should be null
   * for a raw store only. entityClassName is used to identify the store and may not be null.
   */
  public synchronized <PK, E> PrimaryIndex<PK, E> getPrimaryIndex(
      Class<PK> primaryKeyClass,
      String primaryKeyClassName,
      Class<E> entityClass,
      String entityClassName)
      throws DatabaseException {

    assert (rawAccess && entityClass == RawObject.class)
        || (!rawAccess && entityClass != RawObject.class);
    assert (rawAccess && primaryKeyClassName == null)
        || (!rawAccess && primaryKeyClassName != null);

    checkOpen();

    PrimaryIndex<PK, E> priIndex = priIndexMap.get(entityClassName);
    if (priIndex == null) {

      /* Check metadata. */
      EntityMetadata entityMeta = checkEntityClass(entityClassName);
      PrimaryKeyMetadata priKeyMeta = entityMeta.getPrimaryKey();
      if (primaryKeyClassName == null) {
        primaryKeyClassName = priKeyMeta.getClassName();
      } else {
        String expectClsName = SimpleCatalog.keyClassName(priKeyMeta.getClassName());
        if (!primaryKeyClassName.equals(expectClsName)) {
          throw new IllegalArgumentException(
              "Wrong primary key class: "
                  + primaryKeyClassName
                  + " Correct class is: "
                  + expectClsName);
        }
      }

      /* Create bindings. */
      PersistEntityBinding entityBinding =
          new PersistEntityBinding(catalog, entityClassName, rawAccess);
      PersistKeyBinding keyBinding = getKeyBinding(primaryKeyClassName);

      /* If not read-only, get the primary key sequence. */
      String seqName = priKeyMeta.getSequenceName();
      if (!storeConfig.getReadOnly() && seqName != null) {
        entityBinding.keyAssigner =
            new PersistKeyAssigner(keyBinding, entityBinding, getSequence(seqName));
      }

      /*
       * Use a single transaction for opening the primary DB and its
       * secondaries.  If opening any secondary fails, abort the
       * transaction and undo the changes to the state of the store.
       * Also support undo if the store is non-transactional.
       */
      Transaction txn = null;
      DatabaseConfig dbConfig = getPrimaryConfig(entityMeta);
      if (dbConfig.getTransactional() && env.getThreadTransaction() == null) {
        txn = env.beginTransaction(null, null);
      }
      PrimaryOpenState priOpenState = new PrimaryOpenState(entityClassName);
      boolean success = false;
      try {

        /* Open the primary database. */
        String dbName = storePrefix + entityClassName;
        Database db = env.openDatabase(txn, dbName, dbConfig);
        priOpenState.addDatabase(db);

        /* Create index object. */
        priIndex = new PrimaryIndex(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 contratints, 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 {
        if (success) {
          if (txn != null) {
            txn.commit();
          }
        } else {
          if (txn != null) {
            txn.abort();
          } else {
            priOpenState.closeDatabases();
          }
          priOpenState.undoState();
        }
      }
    }
    return priIndex;
  }
Beispiel #23
0
  private void doSecondaryBulkLoad(boolean closeAndOpenNormally) throws DatabaseException {

    PrimaryIndex<Integer, RelatedX> priX;
    PrimaryIndex<Integer, RelatedY> priY;
    SecondaryIndex<Integer, Integer, RelatedX> secX;

    /* Open priX with SecondaryBulkLoad=true. */
    StoreConfig config = new StoreConfig();
    config.setAllowCreate(true);
    config.setSecondaryBulkLoad(true);
    open(config);

    /* Getting priX should not create the secondary index. */
    priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
    PersistTestUtils.assertDbExists(false, env, STORE_NAME, RelatedX.class.getName(), "key2");

    /* We can put records that violate the secondary key constraint. */
    priX.put(new RelatedX());

    if (closeAndOpenNormally) {
      /* Open normally and attempt to populate the secondary. */
      close();
      open();
      if (isTransactional && DbCompat.POPULATE_ENFORCES_CONSTRAINTS) {
        /* Constraint enforcement requires transactions. */
        try {
          /* Before adding the foreign key, constraint is violated. */
          priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
          fail();
        } catch (DatabaseException e) {
          assertTrue(e.toString(), e.toString().contains("foreign key not allowed"));
        }
      }
      /* Open priX with SecondaryBulkLoad=true. */
      close();
      open(config);
      /* Add the foreign key to avoid the constraint error. */
      priY = store.getPrimaryIndex(Integer.class, RelatedY.class);
      priY.put(new RelatedY());
      /* Open normally and the secondary will be populated. */
      close();
      open();
      priX = store.getPrimaryIndex(Integer.class, RelatedX.class);
      PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedX.class.getName(), "key2");
      secX = store.getSecondaryIndex(priX, Integer.class, "key2");
    } else {
      /* Get secondary index explicitly and it will be populated. */
      if (isTransactional && DbCompat.POPULATE_ENFORCES_CONSTRAINTS) {
        /* Constraint enforcement requires transactions. */
        try {
          /* Before adding the foreign key, constraint is violated. */
          secX = store.getSecondaryIndex(priX, Integer.class, "key2");
          fail();
        } catch (DatabaseException e) {
          assertTrue(e.toString(), e.toString().contains("foreign key not allowed"));
        }
      }
      /* Add the foreign key. */
      priY = store.getPrimaryIndex(Integer.class, RelatedY.class);
      priY.put(new RelatedY());
      secX = store.getSecondaryIndex(priX, Integer.class, "key2");
      PersistTestUtils.assertDbExists(true, env, STORE_NAME, RelatedX.class.getName(), "key2");
    }

    RelatedX x = secX.get(88);
    assertNotNull(x);
    close();
  }
Beispiel #24
0
  private void open(StoreConfig config) throws DatabaseException {

    config.setTransactional(envConfig.getTransactional());
    store = new EntityStore(env, STORE_NAME, config);
  }