Question

I'm planning on using Apache Cayenne in a project, but I struggle with getting it actually set up correctly.

The Cayenne tutorial shows how to set a database location in the CayenneModeller. My problem is that I want to use Apache Derby at a path that is determined dynamically at runtime and I can't find out how to actually make Cayenne use that path.

I tried to set the path like this:

private static boolean setupDataBase() {
    String path = Globals.USER_DATA_DIRECTORY + File.separator + "db";
    try {
        DataSource dataSource = new PoolManager(
                "org.apache.derby.jdbc.EmbeddedDriver",
                "jdbc:derby:" + path + ";create=true",
                1,
                1,
                null,
                null
        );
        Configuration configuration = Configuration.getSharedConfiguration();
        DataDomain domain = configuration.getDomain();
        DataNode node = domain.getNode("MaciNode");
        node.setDataSource(dataSource);
        return true;
    } catch (SQLException e) {
        e.printStackTrace();
        return false;
    }
}

But when I later call DataContext.createDataContext(), the log in the console shows this:

Information: Created connection pool: jdbc:derby:memory:testdb;create=true

That is the in-memory test URL I've set in CayenneModeller, not the one I've set in setupDataBase (and yes, I did very that that method gets called). Also, the database files are not created (I verified with the debugger that the path is correct).

So, what is the canonical solution to this problem?

Was it helpful?

Solution

I think the log output you are seeing is from this line:

Configuration configuration = Configuration.getSharedConfiguration()

I.e. the default DataSource is loaded before you install yours. While there are ways to hack 3.0 startup sequence, I would strongly recommend instead to switch to Cayenne 3.1B2. It is on the verge of becoming "RC" and "final", so don't get alarmed by its current Beta status.

One way custom DataSource can be built in 3.1 is by defining a few properties in Cayenne DI module as described here, and letting Cayenne worry about the right startup sequence. Trimming the irrelevant parts of the advice above, you startup code might look like this:

Module m1 = new Module() {

  @Override
  public void configure(Binder binder) {
    binder.bindMap(Constants.PROPERTIES_MAP)
       .put(Constants.JDBC_DRIVER_PROPERTY, "com.my.Driver")
       .put(Constants.JDBC_URL_PROPERTY, "jdbc://db1_url")
       .put(Constants.JDBC_USERNAME_PROPERTY, "db1login")
       .put(Constants.JDBC_PASSWORD_PROPERTY, "db1password");
  }
};

ServerRuntime r1 = new ServerRuntime("cayenne-project.xml", m1);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top