You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by John Huss <jo...@gmail.com> on 2012/12/13 18:43:58 UTC

cayenne.adapter.[domain].[node] property

I believe this property was removed a good while back although it was
present in 3.1 earlier: cayenne.adapter.[domain].[node] property
Why was it removed?  Can we put it back?

I'd like to be able to switch DBs using the properties and doing so
requires changing the adapter, unless of course I use AutoAdapter.  My
problem with AutoAdapter is that is causes a connection to be opened
immediately whereas a hard coded adapter does not.  Does it have to do
that?  I stepped through it before but I've forgotten why it does.

My other problem with AutoAdapter is that you can't access the jdbcLogger
in it -- I think this is probably just an oversight.  Can we add
getJdbcEventLogger from JdbcAdapter into AutoAdapter and DbAdapter?

Thanks,
John

Re: cayenne.adapter.[domain].[node] property

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Dec 14, 2012, at 1:29 AM, John Huss <jo...@gmail.com> wrote:

> Thanks, that helps.  One question below.
> 
>> I believe this property was removed a good while back although it was
>>> present in 3.1 earlier: cayenne.adapter.[domain].[node] property
>>> Why was it removed?  Can we put it back?
>> 
>> You can implement your own DbAdapterFactory that takes adapter name from a
>> property.
>> 
> 
> Sure, but since properties like "cayenne.jdbc.driver" are already provided,
> isn't it incomplete to not provide one for the adapter too?  

I think the 2 objects are different. DataSource information is expected to be fluid across different environments of the same application, and there's no way we can build zero-configuration "AutoDataSource".

> Or are you just assuming people will use AutoAdapter?

Pretty much. It was assumed that between (1) AutoAdapter with its accommodation of possible user adapters via  Constants.SERVER_ADAPTER_DETECTORS_LIST list and (2) user ability to specify a fixed adapter class in the Modeler (see DataNode -> Adapter) we had everybody covered.

So why is AutoAdapter insufficient in your case?

Andrus 

Re: cayenne.adapter.[domain].[node] property

Posted by John Huss <jo...@gmail.com>.
Thanks, that helps.  One question below.

> I believe this property was removed a good while back although it was
> > present in 3.1 earlier: cayenne.adapter.[domain].[node] property
> > Why was it removed?  Can we put it back?
>
> You can implement your own DbAdapterFactory that takes adapter name from a
> property.
>

Sure, but since properties like "cayenne.jdbc.driver" are already provided,
isn't it incomplete to not provide one for the adapter too?  Or are you
just assuming people will use AutoAdapter?

Re: cayenne.adapter.[domain].[node] property

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Dec 24, 2012, at 4:24 PM, John Huss <jo...@gmail.com> wrote:

> My issue above was just that I didn't want to open the connection until I
> started using it.  Sometimes I have DataNodes that can't be used all the
> time because its for a different DB vendor, or for a remote DB that I need
> to open a VPN connection to access, etc.  so it's important that only the
> used nodes will open connections; and they do now that I changed the
> registration of the extended types.

Cool. In fact IIRC AutoAdapter concept was introduced specifically to allow lazy bootstrap of the adapter. We could create an unwrapped adapter, but that would've required calling adapter factory explicitly on startup, and opening a connection immediately. 

Andrus

Re: cayenne.adapter.[domain].[node] property

Posted by John Huss <jo...@gmail.com>.
On Monday, December 24, 2012, Andrus Adamchik wrote:

>
> > Is it necessary to open a connection to the DB to get the metdata in
> order
> > to detect the adapter?  Couldn't you just look at the jdbc url scheme?
>
> Yes. All we have available to Cayenne is a DataSource, which doesn't have
> access to the driver, and can encapsulate various kinds of connection
> pools, which prevents any reliable assertions.
>
> > For migrations I'd like to allow for DB specific sql to be put in
> separate
> > files and then choose the correct file based on which DB is actually
> being
> > used.  I was looking at the Adapter classname for this, but if
> AutoAdapter
> > is used I can't tell what which DB it is.  So would the jdbc url be a
> > reliable source for this info?
>
> > Relatedly, what if AutoAdapter replaced itself with the actual adapter
> > after it was detected?  Wouldn't that be better that delegating?
>
> If possible, I'd like to avoid breaking the decorator. This goes against
> intentional encapsulation of the details.
>
> So can your own code rely on DB metadata, just like various
> DbAdapterDetectors do? A very rich DB information is readily available and
> does not require breaking encapsulation. E.g.:
>
> String jdbcUrl = dataSource.getConnection().getMetadata().getURL();
>
> String dbLabel =
> dataSource.getConnection().getMetadata().getDatabaseProductName();
>
> You said multiple times that you don't want to open a DB connection. But
> why? It should solve all your problems without resorting to "instanceof"
> and such.


This last question is coming from something different.  Opening a
connection is fine. I was just curious why it was neccessary, which you
answered very well.

My issue above was just that I didn't want to open the connection until I
started using it.  Sometimes I have DataNodes that can't be used all the
time because its for a different DB vendor, or for a remote DB that I need
to open a VPN connection to access, etc.  so it's important that only the
used nodes will open connections; and they do now that I changed the
registration of the extended types.


> Andrus
>
>
>
>
>
> On Dec 22, 2012, at 12:45 AM, John Huss <johnthuss@gmail.com<javascript:;>>
> wrote:
>
> > Is it necessary to open a connection to the DB to get the metdata in
> order
> > to detect the adapter?  Couldn't you just look at the jdbc url scheme?
> >
> > For migrations I'd like to allow for DB specific sql to be put in
> separate
> > files and then choose the correct file based on which DB is actually
> being
> > used.  I was looking at the Adapter classname for this, but if
> AutoAdapter
> > is used I can't tell what which DB it is.  So would the jdbc url be a
> > reliable source for this info?
> >
> > Relatedly, what if AutoAdapter replaced itself with the actual adapter
> > after it was detected?  Wouldn't that be better that delegating?
> >
> >
> > On Mon, Dec 17, 2012 at 12:45 AM, Andrus Adamchik <
> andrus@objectstyle.org <javascript:;>>wrote:
> >
> >>
> >> On Dec 16, 2012, at 1:48 AM, John Huss <johnthuss@gmail.com<javascript:;>>
> wrote:
> >>>>
> >>>>> My problem with AutoAdapter is that is causes a connection to be
> opened
> >>>>> immediately whereas a hard coded adapter does not.  Does it have to
> do
> >>>>> that?
> >>>>
> >>>> It shouldn't. Could you provide a stack trace of the call that starts
> >> the
> >>>> connection? Maybe there's something preceding AutoAdapter
> >> initialization,
> >>>> like connection pool creation?
> >>>
> >>>
> >>> Ok, deeper down I was calling
> >>>    dataNode.getAdapter().getExtendedTypes().registerType(...)
> >>> which was forcing the adapter to be loaded.  This appears not to happen
> >> if
> >>> I use the DI binding instead.  So problem solved!
> >>
> >> Cool. Yeah, a notion of ownership of certain objects by certain other
> >> objects (adapter owns ExtendedType, adapter owns PkGenerator, etc) is
> being
> >> obsoleted by DI, but is still reflected in the API. We'll be gradually
> >> cleaning this up.
> >>
> >> Andrus
> >>
> >>
>
>

Re: cayenne.adapter.[domain].[node] property

Posted by Andrus Adamchik <an...@objectstyle.org>.
> Is it necessary to open a connection to the DB to get the metdata in order
> to detect the adapter?  Couldn't you just look at the jdbc url scheme?

Yes. All we have available to Cayenne is a DataSource, which doesn't have access to the driver, and can encapsulate various kinds of connection pools, which prevents any reliable assertions.

> For migrations I'd like to allow for DB specific sql to be put in separate
> files and then choose the correct file based on which DB is actually being
> used.  I was looking at the Adapter classname for this, but if AutoAdapter
> is used I can't tell what which DB it is.  So would the jdbc url be a
> reliable source for this info?

> Relatedly, what if AutoAdapter replaced itself with the actual adapter
> after it was detected?  Wouldn't that be better that delegating?

If possible, I'd like to avoid breaking the decorator. This goes against intentional encapsulation of the details.

So can your own code rely on DB metadata, just like various DbAdapterDetectors do? A very rich DB information is readily available and does not require breaking encapsulation. E.g.:

String jdbcUrl = dataSource.getConnection().getMetadata().getURL();

String dbLabel = dataSource.getConnection().getMetadata().getDatabaseProductName();

You said multiple times that you don't want to open a DB connection. But why? It should solve all your problems without resorting to "instanceof" and such.

Andrus





On Dec 22, 2012, at 12:45 AM, John Huss <jo...@gmail.com> wrote:

> Is it necessary to open a connection to the DB to get the metdata in order
> to detect the adapter?  Couldn't you just look at the jdbc url scheme?
> 
> For migrations I'd like to allow for DB specific sql to be put in separate
> files and then choose the correct file based on which DB is actually being
> used.  I was looking at the Adapter classname for this, but if AutoAdapter
> is used I can't tell what which DB it is.  So would the jdbc url be a
> reliable source for this info?
> 
> Relatedly, what if AutoAdapter replaced itself with the actual adapter
> after it was detected?  Wouldn't that be better that delegating?
> 
> 
> On Mon, Dec 17, 2012 at 12:45 AM, Andrus Adamchik <an...@objectstyle.org>wrote:
> 
>> 
>> On Dec 16, 2012, at 1:48 AM, John Huss <jo...@gmail.com> wrote:
>>>> 
>>>>> My problem with AutoAdapter is that is causes a connection to be opened
>>>>> immediately whereas a hard coded adapter does not.  Does it have to do
>>>>> that?
>>>> 
>>>> It shouldn't. Could you provide a stack trace of the call that starts
>> the
>>>> connection? Maybe there's something preceding AutoAdapter
>> initialization,
>>>> like connection pool creation?
>>> 
>>> 
>>> Ok, deeper down I was calling
>>>    dataNode.getAdapter().getExtendedTypes().registerType(...)
>>> which was forcing the adapter to be loaded.  This appears not to happen
>> if
>>> I use the DI binding instead.  So problem solved!
>> 
>> Cool. Yeah, a notion of ownership of certain objects by certain other
>> objects (adapter owns ExtendedType, adapter owns PkGenerator, etc) is being
>> obsoleted by DI, but is still reflected in the API. We'll be gradually
>> cleaning this up.
>> 
>> Andrus
>> 
>> 


Re: cayenne.adapter.[domain].[node] property

Posted by John Huss <jo...@gmail.com>.
Is it necessary to open a connection to the DB to get the metdata in order
to detect the adapter?  Couldn't you just look at the jdbc url scheme?

For migrations I'd like to allow for DB specific sql to be put in separate
files and then choose the correct file based on which DB is actually being
used.  I was looking at the Adapter classname for this, but if AutoAdapter
is used I can't tell what which DB it is.  So would the jdbc url be a
reliable source for this info?

Relatedly, what if AutoAdapter replaced itself with the actual adapter
after it was detected?  Wouldn't that be better that delegating?


On Mon, Dec 17, 2012 at 12:45 AM, Andrus Adamchik <an...@objectstyle.org>wrote:

>
> On Dec 16, 2012, at 1:48 AM, John Huss <jo...@gmail.com> wrote:
> >>
> >>> My problem with AutoAdapter is that is causes a connection to be opened
> >>> immediately whereas a hard coded adapter does not.  Does it have to do
> >>> that?
> >>
> >> It shouldn't. Could you provide a stack trace of the call that starts
> the
> >> connection? Maybe there's something preceding AutoAdapter
> initialization,
> >> like connection pool creation?
> >
> >
> > Ok, deeper down I was calling
> >     dataNode.getAdapter().getExtendedTypes().registerType(...)
> > which was forcing the adapter to be loaded.  This appears not to happen
> if
> > I use the DI binding instead.  So problem solved!
>
> Cool. Yeah, a notion of ownership of certain objects by certain other
> objects (adapter owns ExtendedType, adapter owns PkGenerator, etc) is being
> obsoleted by DI, but is still reflected in the API. We'll be gradually
> cleaning this up.
>
> Andrus
>
>

Re: cayenne.adapter.[domain].[node] property

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Dec 16, 2012, at 1:48 AM, John Huss <jo...@gmail.com> wrote:
>> 
>>> My problem with AutoAdapter is that is causes a connection to be opened
>>> immediately whereas a hard coded adapter does not.  Does it have to do
>>> that?
>> 
>> It shouldn't. Could you provide a stack trace of the call that starts the
>> connection? Maybe there's something preceding AutoAdapter initialization,
>> like connection pool creation?
> 
> 
> Ok, deeper down I was calling
>     dataNode.getAdapter().getExtendedTypes().registerType(...)
> which was forcing the adapter to be loaded.  This appears not to happen if
> I use the DI binding instead.  So problem solved!

Cool. Yeah, a notion of ownership of certain objects by certain other objects (adapter owns ExtendedType, adapter owns PkGenerator, etc) is being obsoleted by DI, but is still reflected in the API. We'll be gradually cleaning this up.

Andrus


Re: cayenne.adapter.[domain].[node] property

Posted by John Huss <jo...@gmail.com>.
>
> > My problem with AutoAdapter is that is causes a connection to be opened
> > immediately whereas a hard coded adapter does not.  Does it have to do
> > that?
>
> It shouldn't. Could you provide a stack trace of the call that starts the
> connection? Maybe there's something preceding AutoAdapter initialization,
> like connection pool creation?


Ok, deeper down I was calling
     dataNode.getAdapter().getExtendedTypes().registerType(...)
 which was forcing the adapter to be loaded.  This appears not to happen if
I use the DI binding instead.  So problem solved!

Re: cayenne.adapter.[domain].[node] property

Posted by Andrus Adamchik <an...@objectstyle.org>.
Hi John,

Both things - adapter and logger - are injectable. Here is a relevant ServerModule piece:

  binder.bind(DbAdapterFactory.class).to(DefaultDbAdapterFactory.class);
  binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class);

That's a general answer to your questions. See more specifics below...

> I believe this property was removed a good while back although it was
> present in 3.1 earlier: cayenne.adapter.[domain].[node] property
> Why was it removed?  Can we put it back?

You can implement your own DbAdapterFactory that takes adapter name from a property. 

> My problem with AutoAdapter is that is causes a connection to be opened
> immediately whereas a hard coded adapter does not.  Does it have to do
> that? 

It shouldn't. Could you provide a stack trace of the call that starts the connection? Maybe there's something preceding AutoAdapter initialization, like connection pool creation?

> My other problem with AutoAdapter is that you can't access the jdbcLogger
> in it -- I think this is probably just an oversight.  Can we add
> getJdbcEventLogger from JdbcAdapter into AutoAdapter and DbAdapter?

DbAdapter no longer "owns" the logger. Logger is created in DI and is accessible via DI, either via injection or directly:

  JdbcEventLogger logger = runtime.getInjector(JdbcEventLogger.class);

So no need to expose it in the interface.

Andrus

  
On Dec 13, 2012, at 8:43 PM, John Huss <jo...@gmail.com> wrote:

> I believe this property was removed a good while back although it was
> present in 3.1 earlier: cayenne.adapter.[domain].[node] property
> Why was it removed?  Can we put it back?
> 
> I'd like to be able to switch DBs using the properties and doing so
> requires changing the adapter, unless of course I use AutoAdapter.  My
> problem with AutoAdapter is that is causes a connection to be opened
> immediately whereas a hard coded adapter does not.  Does it have to do
> that?  I stepped through it before but I've forgotten why it does.
> 
> My other problem with AutoAdapter is that you can't access the jdbcLogger
> in it -- I think this is probably just an oversight.  Can we add
> getJdbcEventLogger from JdbcAdapter into AutoAdapter and DbAdapter?
> 
> Thanks,
> John