>  but it seems to do that on every call to ObjectContext.commit()! 

We can clean up this code a bit to make sure custom strategies are not 
themselves responsible for synchronization of the call and ensuring a single 
invocation. Though if you extend from BaseSchemaUpdateStrategy or use one of 
the built-in strategies (like SchemaUpdateStrategyFactory) you shouldn't worry 
about this at all. Cayenne will do the right thing.

There's a small overhead in invoking this code in BaseSchemaUpdateStrategy:

  if (!run && (inProgress == null || !inProgress)) ...

But really not that much.

Andrus


> On Oct 12, 2017, at 9:38 PM, Dirk Lattermann <dl...@alqualonde.de> wrote:
> 
> I experimented a bit with the SchemaUpdateStrategyFactory to create a
> test SchemaUpdateStrategy. It is correct that Cayenne calls the
> strategy before any app code can access the DB, but it seems to do that
> on every call to ObjectContext.commit()! That's quite surprising to me
> because I think it would be sufficient to call it only before the first
> database access of a DataNode. If the Strategy is quite expensive (for
> example, using Liquibase), then that has quite a performance impact.
> 
> Is it possibly considered the task of the Factory to return a strategy
> only on the first call to the DataNode? That also would be quite
> surprising to me, but I did not find any documentation about that.
> 
> 
> Am Mon, 9 Oct 2017 09:29:22 +0300
> schrieb Andrus Adamchik <and...@objectstyle.org>:
> 
>> Hi Dirk,
>> 
>> When using explicit transactions [1], the connection is always the
>> same within the transaction. "runtime.performInTransaction(..)" [2]
>> can also take TransactionListener as a second argument that you may
>> implement to set connection properties. 
>> 
>> Unrelated to the above, specifically for schema generation purposes
>> you can bind SchemaUpdateStrategyFactory [3] when you start your
>> runtime, that creates SchemaUpdateStrategy (either one of the
>> standard choices like CreateIfNoSchemaStrategy, or your custom
>> version). Cayenne is guaranteed to invoke the strategy before any of
>> the app code can access the DB.
>> 
>> Hopefully it will point you in the right direction.
>> 
>> Andrus
>> 
>> [1]
>> http://cayenne.apache.org/docs/4.0/cayenne-guide/persistent-objects-objectcontext.html#transactions
>> [2]
>> https://cayenne.apache.org/docs/4.0/api/index.html?org/apache/cayenne/configuration/server/ServerRuntime.html
>> [3]
>> https://cayenne.apache.org/docs/4.0/api/org/apache/cayenne/access/dbsync/SchemaUpdateStrategyFactory.html
>> 
>> 
>>> On Oct 8, 2017, at 12:39 PM, Dirk Lattermann <dl...@alqualonde.de>
>>> wrote:
>>> 
>>> Hello,
>>> 
>>> is it possible to control which database connection is used when
>>> committing an ObjectContext?
>>> 
>>> For example, when using an explicit transaction, the database
>>> connection used in the thread starting the exception must always be
>>> the same.
>>> 
>>> Now, I have a use case where I want to obtain a PostgresQL advisory
>>> exclusive session lock and do some DDL to create a db schema. Then I
>>> want to write something into that schema using Cayenne, and after
>>> that, release the lock. That's to somewhat atomically initialize a
>>> db schema.
>>> 
>>> For normal schema usage, I want to obtain an advisory shared lock
>>> in the db connection and use that connection with Cayenne.
>>> 
>>> That mechanism can also be used to manipulate portions of the
>>> database that must be done without concurrent access.
>>> 
>>> It's how I solved the problem with Hibernate, where a Hibernate
>>> session represents a JDBC Connection. It is bound to the current
>>> thread and used for all Hibernate DB accesses during the session.
>>> That worked quite well.
>>> 
>>> Would it be possible to do something similar with Cayenne?  
>> 
> 

Reply via email to