You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cayenne.apache.org by Andrey Razumovsky <ra...@gmail.com> on 2009/06/01 17:09:47 UTC

Non-physical delete... again

Hi,

We've discussed this time ago, but I'm back now with some ideas.

Current situation:
I have to use special boolean column named "deleted" in all DB tables. That
is, I never (or very rarely) do something like "DELETE FROM ..." or
"context.deleteObject()", instead I do "UPDATE... SET deleted=true" or
cdo.setDeleted(true). To select only undeleted records, I add qualifier like
"deleted=true" to every ObjEntity. Also I add pre-update listeners to all
entities which unregisters object and processes delete rules (also
respective to 'deleted' field) if 'deleted' flag is set.
It is obvious that Cayenne cannot completely handle this situation. One
example is CAY-1109, but it can be workarounded as described above. More
serious problems are:
- I cannot use properly flattened relationships, because 'deleted' qualifier
is not applied to DBEntities selection (e.g. in 'medium' table of
many-to-many relationship)
- flattened expressions, e.g. toArtist.name="Rublev" also miss that
qualifier
- there is no objects with DELETED state, only with MODIFIED
...and so on.

I faced this situation since the first days I used Cayenne. Now when I
thought about this a bit, I think I can handle it with two new features. I'm
not sure they completely match Cayenne paradigm, but...

1. DBEntity qualifier. This is same as ObjEntity qualifier, but applied
every time DBentity is being added to select sql. I will add DBEntity
qualifier 'deleted=false' and drop current ObjEntity's

2.  Deletion strategy for DataDomain. This means I do not always fire
DeleteAction, but maybe something else (update action in my case).

Any comments much appreciated.

Thanks,
Andrey

Re: IOC container

Posted by Michael Gentry <mg...@masslight.net>.
I think getting rid of DataDomains (at least in the Modeler) ties into
my #1 here:

http://markmail.org/message/wf7y73rgorj4bi4h

mrg


On Mon, Nov 16, 2009 at 9:43 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
> And finally, unrelated, but since DataDomains were mentioned... I've been
> thinking to do away with multiple DataDomains. They are really independent
> stacks, so why bother keeping them together in one project. The users can
> start multiple Cayenne stacks instead.

Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
Yeah, it's been briefly mentioned in this thread: http://markmail.org/message/xyyixpaolg45cj4x

The spec jar is just 4K. The annotations that I used are compatible  
with it, so if during development we decide it makes sense to stay  
standard-compliant in this case, it won't be a problem to switch.

(BTW, SVN is back up and I checked in the remaining provider code).

Andrus


On Nov 16, 2009, at 8:54 AM, Andrey Razumovsky wrote:

> Hi,
>
> I'm not sure it will be helpful, but there's JSR-330 spec for that  
> (instead
> of borrowing straightly from Guice):
> http://jcp.org/aboutJava/communityprocess/final/jsr330/index.html
>
> It defines several useful classes and annotations, as @Inject and
> Provider<T>
>
> 2009/11/16 Andrus Adamchik <an...@objectstyle.org>
>
>> Just for kicks wrote a simple DI container for Cayenne. I checked  
>> it in
>> partially to sanbdox folder until the ASF SVN repo went down (
>> http://monitoring.apache.org/), so I'll commit the rest on Monday, or
>> whenever SVN becomes available.
>>
>> This no-frills DI container took me only a couple of hours to write  
>> (it
>> borrows some Guice API, but implementation is all mine). It supports
>>
>> * annotation-based field dependency injection
>> * binding interfaces to implementation classes via fluent API
>> * binding interfaces to "provider" (same as "factory") classes
>> * merging multiple DI "modules".
>>
>> The whole thing is only 14K after compilation (so it beats all full
>> featured DI containers in size). Of course that's because it  
>> doesn't have
>> all the fancy stuff (of which we'll add at least a few more things)  
>> such as
>> constructor injection, dependency cycle resolving, dynamic interface
>> proxies, bound object lifecycle, integration with Spring, etc.  
>> Since we are
>> not planning a general purpose container, we might survive without  
>> most of
>> those.
>>
>> Here is how the current Configuration class might look like when it  
>> is
>> based on DI:
>>
>> public class Configuration {
>>
>>       private Injector injector;
>>
>>       public Configuration() {
>>               this(new CayenneModule());
>>       }
>>
>>       public Configuration(Module... modules) {
>>               this.injector = DIBootstrap.createInjector(modules);
>>       }
>>
>>       public DataChannel getDataChannel() {
>>               return injector.getInstance(DataChannel.class);
>>       }
>>
>>       public ObjectContext getNewContext() {
>>               return injector.getInstance(ObjectContext.class);
>>       }
>>
>>       // we may create getters for other "services" if we need to
>> }
>>
>> And the actual configuration class (aka "module") used above:
>>
>> public class CayenneModule implements Module {
>>
>>       public void configure(Binder binder) {
>>                
>> binder.bind(EventManager.class).to(EventManagerImpl.class);
>>               binder.bind(DataChannel.class).to(DataDomain.class);
>>
>> binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>>
>> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
>>               // an so on...
>>       }
>> }
>>
>> "CayenneModule" is what users can override (e.g. simply subclass),
>> providing alternative implementations for some services.
>>
>> The next step in this prototype would be an attempt to define the  
>> current
>> Cayenne stack in terms of DI.
>>
>> Andrus
>>
>>
>> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>>
>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org 
>> >
>>> wrote:
>>>
>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)  
>>> support
>>>> the annotations from this JSR. So it could make sense for us to  
>>>> use these
>>>> annotations internally as well. Couldn't dig any info on the  
>>>> Tapestry IoC
>>>> support for this JSR, but they are on the JSR "support group", so  
>>>> at
>>>> least
>>>> they are watching it.
>>>>
>>>
>>> Thiago, the Tapestry member on the support group, just learned  
>>> that it
>>> had been approved.  Howard didn't even know the JSR existed.   
>>> There's
>>> no discussion on adding in the annotation support to Tapestry IoC  
>>> and
>>> I suspect it will happen, but Tapestry is behind the ball on that  
>>> one.
>>>
>>> --
>>> Kevin
>>>
>>>
>>
>
>
> -- 
> Andrey


Re: IOC container

Posted by Andrey Razumovsky <ra...@gmail.com>.
Hi,

I'm not sure it will be helpful, but there's JSR-330 spec for that (instead
of borrowing straightly from Guice):
http://jcp.org/aboutJava/communityprocess/final/jsr330/index.html

It defines several useful classes and annotations, as @Inject and
Provider<T>

2009/11/16 Andrus Adamchik <an...@objectstyle.org>

> Just for kicks wrote a simple DI container for Cayenne. I checked it in
> partially to sanbdox folder until the ASF SVN repo went down (
> http://monitoring.apache.org/), so I'll commit the rest on Monday, or
> whenever SVN becomes available.
>
> This no-frills DI container took me only a couple of hours to write (it
> borrows some Guice API, but implementation is all mine). It supports
>
> * annotation-based field dependency injection
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules".
>
> The whole thing is only 14K after compilation (so it beats all full
> featured DI containers in size). Of course that's because it doesn't have
> all the fancy stuff (of which we'll add at least a few more things) such as
> constructor injection, dependency cycle resolving, dynamic interface
> proxies, bound object lifecycle, integration with Spring, etc. Since we are
> not planning a general purpose container, we might survive without most of
> those.
>
> Here is how the current Configuration class might look like when it is
> based on DI:
>
> public class Configuration {
>
>        private Injector injector;
>
>        public Configuration() {
>                this(new CayenneModule());
>        }
>
>        public Configuration(Module... modules) {
>                this.injector = DIBootstrap.createInjector(modules);
>        }
>
>        public DataChannel getDataChannel() {
>                return injector.getInstance(DataChannel.class);
>        }
>
>        public ObjectContext getNewContext() {
>                return injector.getInstance(ObjectContext.class);
>        }
>
>        // we may create getters for other "services" if we need to
> }
>
> And the actual configuration class (aka "module") used above:
>
> public class CayenneModule implements Module {
>
>        public void configure(Binder binder) {
>                binder.bind(EventManager.class).to(EventManagerImpl.class);
>                binder.bind(DataChannel.class).to(DataDomain.class);
>
>  binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>
>  binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
>                // an so on...
>        }
> }
>
> "CayenneModule" is what users can override (e.g. simply subclass),
> providing alternative implementations for some services.
>
> The next step in this prototype would be an attempt to define the current
> Cayenne stack in terms of DI.
>
> Andrus
>
>
> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>
>  On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <an...@objectstyle.org>
>> wrote:
>>
>>  And I just discovered that both Spring (3.0RC1) and Juice (trunk) support
>>> the annotations from this JSR. So it could make sense for us to use these
>>> annotations internally as well. Couldn't dig any info on the Tapestry IoC
>>> support for this JSR, but they are on the JSR "support group", so at
>>> least
>>> they are watching it.
>>>
>>
>> Thiago, the Tapestry member on the support group, just learned that it
>> had been approved.  Howard didn't even know the JSR existed.  There's
>> no discussion on adding in the annotation support to Tapestry IoC and
>> I suspect it will happen, but Tapestry is behind the ball on that one.
>>
>> --
>> Kevin
>>
>>
>


-- 
Andrey

Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Nov 16, 2009, at 4:43 PM, Andrus Adamchik wrote:

> I don't have all the details yet, but the container API will be  
> extended as needed to fit our needs. For now I am thinking that all  
> cases where we need to access objects by name, will be delegated to  
> Configuration and other objects outside container. The container may  
> store maps of all names, and Configuration will be a frontend to  
> read from those maps.

I should also mention that I am not fully clear yet about a separation  
between the "container services" and "model objects" defined in the  
XML project. Certain things (such as JGroups configuration) do not  
belong in the project and should be re-classified as container  
services. DataDomain / DataNodes are somewhat in the middle. Their  
structure is defined by the user, but Cayenne injects all services  
they need to operate.

Will need to play with it a bit more, but the direction is to keep the  
environment agnostic model (DataMap) separate from environment- 
specific stuff (access stack). Modeling access stack in the modeler is  
a nice shortcut to get people started, but doesn't address JEE  
environment complexity well.

Andrus


Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
Do you mean multiple DataDomains?

I don't have all the details yet, but the container API will be  
extended as needed to fit our needs. For now I am thinking that all  
cases where we need to access objects by name, will be delegated to  
Configuration and other objects outside container. The container may  
store maps of all names, and Configuration will be a frontend to read  
from those maps.

But if we find that extending the container is beneficial, we can do  
that too. E.g. I am planning something similar to Tapestry  
configurations for the users to register/override ExtendedTypes, so  
that the users don't have to redefine all types if they need to add  
just one extra object.

Also to ensure we are on the same page, I am not planning app-facing  
injection, just internal injection of Cayenne classes between  
themselves. I.e. we won't inject anything in an app class that is  
calling an ObjectContext (unless it is an override for the standard  
service).

And finally, unrelated, but since DataDomains were mentioned... I've  
been thinking to do away with multiple DataDomains. They are really  
independent stacks, so why bother keeping them together in one  
project. The users can start multiple Cayenne stacks instead.

Andrus


On Nov 16, 2009, at 4:28 PM, Michael Gentry wrote:
> How are you envisioning injecting an ObjectContext for different  
> DataNodes, etc?
>
> Thanks,
>
> mrg
>
>
> On Sun, Nov 15, 2009 at 4:57 PM, Andrus Adamchik <andrus@objectstyle.org 
> > wrote:
>> Just for kicks wrote a simple DI container for Cayenne. I checked  
>> it in
>> partially to sanbdox folder until the ASF SVN repo went down
>> (http://monitoring.apache.org/), so I'll commit the rest on Monday,  
>> or
>> whenever SVN becomes available.
>>
>> This no-frills DI container took me only a couple of hours to write  
>> (it
>> borrows some Guice API, but implementation is all mine). It supports
>>
>> * annotation-based field dependency injection
>> * binding interfaces to implementation classes via fluent API
>> * binding interfaces to "provider" (same as "factory") classes
>> * merging multiple DI "modules".
>>
>> The whole thing is only 14K after compilation (so it beats all full  
>> featured
>> DI containers in size). Of course that's because it doesn't have  
>> all the
>> fancy stuff (of which we'll add at least a few more things) such as
>> constructor injection, dependency cycle resolving, dynamic interface
>> proxies, bound object lifecycle, integration with Spring, etc.  
>> Since we are
>> not planning a general purpose container, we might survive without  
>> most of
>> those.
>>
>> Here is how the current Configuration class might look like when it  
>> is based
>> on DI:
>>
>> public class Configuration {
>>
>>        private Injector injector;
>>
>>        public Configuration() {
>>                this(new CayenneModule());
>>        }
>>
>>        public Configuration(Module... modules) {
>>                this.injector = DIBootstrap.createInjector(modules);
>>        }
>>
>>        public DataChannel getDataChannel() {
>>                return injector.getInstance(DataChannel.class);
>>        }
>>
>>        public ObjectContext getNewContext() {
>>                return injector.getInstance(ObjectContext.class);
>>        }
>>
>>        // we may create getters for other "services" if we need to
>> }
>>
>> And the actual configuration class (aka "module") used above:
>>
>> public class CayenneModule implements Module {
>>
>>        public void configure(Binder binder) {
>>                 
>> binder.bind(EventManager.class).to(EventManagerImpl.class);
>>                binder.bind(DataChannel.class).to(DataDomain.class);
>>
>>  binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>>                 
>> binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
>>                // an so on...
>>        }
>> }
>>
>> "CayenneModule" is what users can override (e.g. simply subclass),  
>> providing
>> alternative implementations for some services.
>>
>> The next step in this prototype would be an attempt to define the  
>> current
>> Cayenne stack in terms of DI.
>>
>> Andrus
>>
>> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>>
>>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org 
>>> >
>>> wrote:
>>>
>>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)  
>>>> support
>>>> the annotations from this JSR. So it could make sense for us to  
>>>> use these
>>>> annotations internally as well. Couldn't dig any info on the  
>>>> Tapestry IoC
>>>> support for this JSR, but they are on the JSR "support group", so  
>>>> at
>>>> least
>>>> they are watching it.
>>>
>>> Thiago, the Tapestry member on the support group, just learned  
>>> that it
>>> had been approved.  Howard didn't even know the JSR existed.   
>>> There's
>>> no discussion on adding in the annotation support to Tapestry IoC  
>>> and
>>> I suspect it will happen, but Tapestry is behind the ball on that  
>>> one.
>>>
>>> --
>>> Kevin
>>>
>>
>>
>


Re: IOC container

Posted by Michael Gentry <mg...@masslight.net>.
How are you envisioning injecting an ObjectContext for different DataNodes, etc?

Thanks,

mrg


On Sun, Nov 15, 2009 at 4:57 PM, Andrus Adamchik <an...@objectstyle.org> wrote:
> Just for kicks wrote a simple DI container for Cayenne. I checked it in
> partially to sanbdox folder until the ASF SVN repo went down
> (http://monitoring.apache.org/), so I'll commit the rest on Monday, or
> whenever SVN becomes available.
>
> This no-frills DI container took me only a couple of hours to write (it
> borrows some Guice API, but implementation is all mine). It supports
>
> * annotation-based field dependency injection
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules".
>
> The whole thing is only 14K after compilation (so it beats all full featured
> DI containers in size). Of course that's because it doesn't have all the
> fancy stuff (of which we'll add at least a few more things) such as
> constructor injection, dependency cycle resolving, dynamic interface
> proxies, bound object lifecycle, integration with Spring, etc. Since we are
> not planning a general purpose container, we might survive without most of
> those.
>
> Here is how the current Configuration class might look like when it is based
> on DI:
>
> public class Configuration {
>
>        private Injector injector;
>
>        public Configuration() {
>                this(new CayenneModule());
>        }
>
>        public Configuration(Module... modules) {
>                this.injector = DIBootstrap.createInjector(modules);
>        }
>
>        public DataChannel getDataChannel() {
>                return injector.getInstance(DataChannel.class);
>        }
>
>        public ObjectContext getNewContext() {
>                return injector.getInstance(ObjectContext.class);
>        }
>
>        // we may create getters for other "services" if we need to
> }
>
> And the actual configuration class (aka "module") used above:
>
> public class CayenneModule implements Module {
>
>        public void configure(Binder binder) {
>                binder.bind(EventManager.class).to(EventManagerImpl.class);
>                binder.bind(DataChannel.class).to(DataDomain.class);
>
>  binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
>                binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
>                // an so on...
>        }
> }
>
> "CayenneModule" is what users can override (e.g. simply subclass), providing
> alternative implementations for some services.
>
> The next step in this prototype would be an attempt to define the current
> Cayenne stack in terms of DI.
>
> Andrus
>
> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>
>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <an...@objectstyle.org>
>> wrote:
>>
>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk) support
>>> the annotations from this JSR. So it could make sense for us to use these
>>> annotations internally as well. Couldn't dig any info on the Tapestry IoC
>>> support for this JSR, but they are on the JSR "support group", so at
>>> least
>>> they are watching it.
>>
>> Thiago, the Tapestry member on the support group, just learned that it
>> had been approved.  Howard didn't even know the JSR existed.  There's
>> no discussion on adding in the annotation support to Tapestry IoC and
>> I suspect it will happen, but Tapestry is behind the ball on that one.
>>
>> --
>> Kevin
>>
>
>

Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Nov 21, 2009, at 11:49 PM, Andrus Adamchik wrote:

>
> * annotation-based field dependency injection
> * annotation-based constructor dependency injection
> * injection of map and list "configurations" (allows to add things  
> like extra ExtendedTypes)
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules"
> * dependency cycle detection

[one more]

* standard and user-defined scopes for bound objects.

Andrus


Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
Just finished all the main features I'd like to see in the DI  
container. So here is a new checklist:

* annotation-based field dependency injection
* annotation-based constructor dependency injection
* injection of map and list "configurations" (allows to add things  
like extra ExtendedTypes)
* binding interfaces to implementation classes via fluent API
* binding interfaces to "provider" (same as "factory") classes
* merging multiple DI "modules"
* dependency cycle detection

The container is still pretty small (all the di package classes are  
~26K when compiled), and it seems like it was worth the effort (vs.  
just using Guice for instance).

Now will try to find time to define a Cayenne stack based on the DI,  
instead of the old Configuration:

https://svn.apache.org/repos/asf/cayenne/sandbox/cayenne-di/src/main/java/org/apache/cayenne/runtime/

Andrus


On Nov 15, 2009, at 11:57 PM, Andrus Adamchik wrote:

> Just for kicks wrote a simple DI container for Cayenne. I checked it  
> in partially to sanbdox folder until the ASF SVN repo went down (http://monitoring.apache.org/ 
> ), so I'll commit the rest on Monday, or whenever SVN becomes  
> available.
>
> This no-frills DI container took me only a couple of hours to write  
> (it borrows some Guice API, but implementation is all mine). It  
> supports
>
> * annotation-based field dependency injection
> * binding interfaces to implementation classes via fluent API
> * binding interfaces to "provider" (same as "factory") classes
> * merging multiple DI "modules".
>
> The whole thing is only 14K after compilation (so it beats all full  
> featured DI containers in size). Of course that's because it doesn't  
> have all the fancy stuff (of which we'll add at least a few more  
> things) such as constructor injection, dependency cycle resolving,  
> dynamic interface proxies, bound object lifecycle, integration with  
> Spring, etc. Since we are not planning a general purpose container,  
> we might survive without most of those.
>
> Here is how the current Configuration class might look like when it  
> is based on DI:
>
> public class Configuration {
>
> 	private Injector injector;
>
> 	public Configuration() {
> 		this(new CayenneModule());
> 	}
>
> 	public Configuration(Module... modules) {
> 		this.injector = DIBootstrap.createInjector(modules);
> 	}
>
> 	public DataChannel getDataChannel() {
> 		return injector.getInstance(DataChannel.class);
> 	}
>
> 	public ObjectContext getNewContext() {
> 		return injector.getInstance(ObjectContext.class);
> 	}
>
> 	// we may create getters for other "services" if we need to
> }
>
> And the actual configuration class (aka "module") used above:
>
> public class CayenneModule implements Module {
>
> 	public void configure(Binder binder) {
> 		binder.bind(EventManager.class).to(EventManagerImpl.class);
> 		binder.bind(DataChannel.class).to(DataDomain.class);
> 		binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
> 		binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
> 		// an so on...
> 	}
> }
>
> "CayenneModule" is what users can override (e.g. simply subclass),  
> providing alternative implementations for some services.
>
> The next step in this prototype would be an attempt to define the  
> current Cayenne stack in terms of DI.
>
> Andrus
>
> On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:
>
>> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org 
>> > wrote:
>>
>>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)  
>>> support
>>> the annotations from this JSR. So it could make sense for us to  
>>> use these
>>> annotations internally as well. Couldn't dig any info on the  
>>> Tapestry IoC
>>> support for this JSR, but they are on the JSR "support group", so  
>>> at least
>>> they are watching it.
>>
>> Thiago, the Tapestry member on the support group, just learned that  
>> it
>> had been approved.  Howard didn't even know the JSR existed.  There's
>> no discussion on adding in the annotation support to Tapestry IoC and
>> I suspect it will happen, but Tapestry is behind the ball on that  
>> one.
>>
>> -- 
>> Kevin
>>
>
>


Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
Just for kicks wrote a simple DI container for Cayenne. I checked it  
in partially to sanbdox folder until the ASF SVN repo went down (http://monitoring.apache.org/ 
), so I'll commit the rest on Monday, or whenever SVN becomes available.

This no-frills DI container took me only a couple of hours to write  
(it borrows some Guice API, but implementation is all mine). It supports

* annotation-based field dependency injection
* binding interfaces to implementation classes via fluent API
* binding interfaces to "provider" (same as "factory") classes
* merging multiple DI "modules".

The whole thing is only 14K after compilation (so it beats all full  
featured DI containers in size). Of course that's because it doesn't  
have all the fancy stuff (of which we'll add at least a few more  
things) such as constructor injection, dependency cycle resolving,  
dynamic interface proxies, bound object lifecycle, integration with  
Spring, etc. Since we are not planning a general purpose container, we  
might survive without most of those.

Here is how the current Configuration class might look like when it is  
based on DI:

public class Configuration {

	private Injector injector;

	public Configuration() {
		this(new CayenneModule());
	}

	public Configuration(Module... modules) {
		this.injector = DIBootstrap.createInjector(modules);
	}

	public DataChannel getDataChannel() {
		return injector.getInstance(DataChannel.class);
	}

	public ObjectContext getNewContext() {
		return injector.getInstance(ObjectContext.class);
	}

	// we may create getters for other "services" if we need to
}

And the actual configuration class (aka "module") used above:

public class CayenneModule implements Module {

	public void configure(Binder binder) {
		binder.bind(EventManager.class).to(EventManagerImpl.class);
		binder.bind(DataChannel.class).to(DataDomain.class);
		binder.bind(QueryCache.class).toProvider(LRUCacheFactory.class);
		binder.bind(QueryLogger.class).toProvider(FancyLogger.class);
		// an so on...
	}
}

"CayenneModule" is what users can override (e.g. simply subclass),  
providing alternative implementations for some services.

The next step in this prototype would be an attempt to define the  
current Cayenne stack in terms of DI.

Andrus

On Oct 27, 2009, at 11:01 PM, Kevin Menard wrote:

> On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <andrus@objectstyle.org 
> > wrote:
>
>> And I just discovered that both Spring (3.0RC1) and Juice (trunk)  
>> support
>> the annotations from this JSR. So it could make sense for us to use  
>> these
>> annotations internally as well. Couldn't dig any info on the  
>> Tapestry IoC
>> support for this JSR, but they are on the JSR "support group", so  
>> at least
>> they are watching it.
>
> Thiago, the Tapestry member on the support group, just learned that it
> had been approved.  Howard didn't even know the JSR existed.  There's
> no discussion on adding in the annotation support to Tapestry IoC and
> I suspect it will happen, but Tapestry is behind the ball on that one.
>
> -- 
> Kevin
>


Re: IOC container

Posted by Kevin Menard <ni...@gmail.com>.
On Sun, Oct 25, 2009 at 5:05 PM, Andrus Adamchik <an...@objectstyle.org> wrote:

> And I just discovered that both Spring (3.0RC1) and Juice (trunk) support
> the annotations from this JSR. So it could make sense for us to use these
> annotations internally as well. Couldn't dig any info on the Tapestry IoC
> support for this JSR, but they are on the JSR "support group", so at least
> they are watching it.

Thiago, the Tapestry member on the support group, just learned that it
had been approved.  Howard didn't even know the JSR existed.  There's
no discussion on adding in the annotation support to Tapestry IoC and
I suspect it will happen, but Tapestry is behind the ball on that one.

-- 
Kevin

Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
I've been pondering on how a Cayenne IoC "bridge" might work. My  
initial idea was something like an inverted "commons-logging". Spring/ 
Guice/Tapestry users would explicitly bind a Cayenne stack to a  
respective container using some "binder" class that we provide,  
specific to each container (unlike commons-logging that tries to guess  
the environment, causing occasional grief). In the absence of an  
external container Cayenne will use a very simple bundled container,  
essentially a map of interfaces vs services loaded from a classpath  
file.

There's also a JSR-330 that aims at standardizing injection annotations:

http://www.infoq.com/news/2009/08/dependency-injection-javaee6

And I just discovered that both Spring (3.0RC1) and Juice (trunk)  
support the annotations from this JSR. So it could make sense for us  
to use these annotations internally as well. Couldn't dig any info on  
the Tapestry IoC support for this JSR, but they are on the JSR  
"support group", so at least they are watching it.

Anyways, will need to experiment with it a bit and see how easy it is  
to redefine internal Cayenne "services" from the application.

Andrus




On Jun 3, 2009, at 3:02 PM, Andrus Adamchik wrote:

> Right... I envision lots of trouble integrating this into regular  
> JEE ecosystem. My current idea is to use built-in container only if  
> an app has no other container, and load Cayenne configs via an app  
> container otherwise, so that there's only one configuration registry.
>
> Andrus
>
> On Jun 3, 2009, at 2:42 PM, Malcolm Edgar wrote:
>
>> One concern I have about introducing a 3rd party IoC container is
>> class loader conflicts which may occur with including a popular IoC
>> container.  As Cayenne may have a dependency on version X but the
>> application uses version Y.
>>
>> regards Malcolm Edgar
>>
>> On Wed, Jun 3, 2009 at 6:03 AM, Andrus Adamchik <andrus@objectstyle.org 
>> > wrote:
>>> I have a good opinion about Tapestry IoC approach in general  
>>> (including the
>>> now defunct Hivemind), and I wanted to investigate Guice.
>>>
>>> There's some conflicting requirements to address here - we don't  
>>> want to
>>> write/maintain our own IoC container, yet, we don't want to embed  
>>> a huge
>>> third-party engine, of which we'll use only a subset of features.  
>>> I'd like
>>> it to work standalone, as well as be able to integrate (or at  
>>> least play
>>> well) with popular IoC containers (how many containers in one app  
>>> is too
>>> many?). Then there's a matter of modeler support, which is adverse  
>>> to
>>> annotations, and favors XML or other config files...
>>>
>>> All in all, I think assembling a core of Cayenne stack via such a  
>>> container
>>> should open some interesting possibilities, beyond organizing  
>>> current
>>> configuration.
>>>
>>> Andrus
>>>
>>>
>>>
>>> On Jun 2, 2009, at 6:53 PM, Robert Zeigler wrote:
>>>>
>>>> If you're really considering going the 3rd party ioc route, I  
>>>> highly
>>>> recommend T5IOC.
>>>> Note that configuration is (typically) done via code in T5IOC,  
>>>> but I find
>>>> it extremely flexible & powerful, while still being simple to use  
>>>> (and
>>>> small! :).
>>>> If not that, then guice. I'd even go for pico (though preferably  
>>>> not).
>>>> Anything but the monster that spring has become. ;)
>>>>
>>>> Robert
>>>>
>>>> On Jun 2, 2009, at 6/29:02 AM , Andrus Adamchik wrote:
>>>>
>>>>>
>>>>> On Jun 2, 2009, at 4:38 PM, Andrus Adamchik wrote:
>>>>>
>>>>>>>
>>>>>>> Modeler support will be covered by setting class name of  
>>>>>>> strategy
>>>>>>
>>>>>> I am afraid this approach will be rather arbitrary to the end  
>>>>>> user, so I
>>>>>> suggest we discuss it some more before putting it in Cayenne.  
>>>>>> Marking an
>>>>>> entity to use "soft delete" based on some criteria is a clear and
>>>>>> understandable feature. Setting a "delete strategy" is not, and  
>>>>>> will
>>>>>> contribute to confusion. This is totally be ok as a backend  
>>>>>> extension point,
>>>>>> but I will hate to see that as a general use feature.
>>>>>
>>>>> In this context let me mention one idea for Cayenne 3.0 + N,  
>>>>> that I've
>>>>> been thinking about for some time. I am taking this to a  
>>>>> separate thread to
>>>>> avoid distraction from the soft delete discussion, which has  
>>>>> only tangential
>>>>> relevance.
>>>>>
>>>>> Since we already have a bunch of extension points throughout the  
>>>>> stack,
>>>>> some exposed via the Modeler (misplaced like cache JGroups  
>>>>> config, or
>>>>> justified like Adapter config), and some are available only via  
>>>>> the code, we
>>>>> need a way to reign them in. The standard way of doing that is  
>>>>> via an IoC
>>>>> container.
>>>>>
>>>>> No, I don't want to bundle Spring with Cayenne, besides it has to
>>>>> integrate with the larger app ecosystem, so we still need to  
>>>>> figure the
>>>>> technical details. But the point is that we will be able to  
>>>>> provide a single
>>>>> place to configure all extension points, separate from the  
>>>>> mapping. As
>>>>> unlike the mapping those parameters are often different for the  
>>>>> same
>>>>> project, depending on the environment where it is deployed.
>>>>>
>>>>> Right now this place is cayenne.xml (and it might as well stay  
>>>>> this way
>>>>> in the future), just that unlike say Spring config files, it has  
>>>>> a rigid
>>>>> structure and is not generic enough to handle arbitrary  
>>>>> extensions and
>>>>> dependencies. It was ok for the early versions of Cayenne, since  
>>>>> there was
>>>>> only a few things you could change (data source factory and  
>>>>> adapter I
>>>>> believe). But now something more powerful and clean is desirable.
>>>>>
>>>>> Just some raw thoughts.
>>>>>
>>>>> Andrus
>>>>
>>>>
>>>
>>>
>>
>
>


Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
Right... I envision lots of trouble integrating this into regular JEE  
ecosystem. My current idea is to use built-in container only if an app  
has no other container, and load Cayenne configs via an app container  
otherwise, so that there's only one configuration registry.

Andrus

On Jun 3, 2009, at 2:42 PM, Malcolm Edgar wrote:

> One concern I have about introducing a 3rd party IoC container is
> class loader conflicts which may occur with including a popular IoC
> container.  As Cayenne may have a dependency on version X but the
> application uses version Y.
>
> regards Malcolm Edgar
>
> On Wed, Jun 3, 2009 at 6:03 AM, Andrus Adamchik <andrus@objectstyle.org 
> > wrote:
>> I have a good opinion about Tapestry IoC approach in general  
>> (including the
>> now defunct Hivemind), and I wanted to investigate Guice.
>>
>> There's some conflicting requirements to address here - we don't  
>> want to
>> write/maintain our own IoC container, yet, we don't want to embed a  
>> huge
>> third-party engine, of which we'll use only a subset of features.  
>> I'd like
>> it to work standalone, as well as be able to integrate (or at least  
>> play
>> well) with popular IoC containers (how many containers in one app  
>> is too
>> many?). Then there's a matter of modeler support, which is adverse to
>> annotations, and favors XML or other config files...
>>
>> All in all, I think assembling a core of Cayenne stack via such a  
>> container
>> should open some interesting possibilities, beyond organizing current
>> configuration.
>>
>> Andrus
>>
>>
>>
>> On Jun 2, 2009, at 6:53 PM, Robert Zeigler wrote:
>>>
>>> If you're really considering going the 3rd party ioc route, I highly
>>> recommend T5IOC.
>>> Note that configuration is (typically) done via code in T5IOC, but  
>>> I find
>>> it extremely flexible & powerful, while still being simple to use  
>>> (and
>>> small! :).
>>> If not that, then guice. I'd even go for pico (though preferably  
>>> not).
>>>  Anything but the monster that spring has become. ;)
>>>
>>> Robert
>>>
>>> On Jun 2, 2009, at 6/29:02 AM , Andrus Adamchik wrote:
>>>
>>>>
>>>> On Jun 2, 2009, at 4:38 PM, Andrus Adamchik wrote:
>>>>
>>>>>>
>>>>>> Modeler support will be covered by setting class name of strategy
>>>>>
>>>>> I am afraid this approach will be rather arbitrary to the end  
>>>>> user, so I
>>>>> suggest we discuss it some more before putting it in Cayenne.  
>>>>> Marking an
>>>>> entity to use "soft delete" based on some criteria is a clear and
>>>>> understandable feature. Setting a "delete strategy" is not, and  
>>>>> will
>>>>> contribute to confusion. This is totally be ok as a backend  
>>>>> extension point,
>>>>> but I will hate to see that as a general use feature.
>>>>
>>>> In this context let me mention one idea for Cayenne 3.0 + N, that  
>>>> I've
>>>> been thinking about for some time. I am taking this to a separate  
>>>> thread to
>>>> avoid distraction from the soft delete discussion, which has only  
>>>> tangential
>>>> relevance.
>>>>
>>>> Since we already have a bunch of extension points throughout the  
>>>> stack,
>>>> some exposed via the Modeler (misplaced like cache JGroups  
>>>> config, or
>>>> justified like Adapter config), and some are available only via  
>>>> the code, we
>>>> need a way to reign them in. The standard way of doing that is  
>>>> via an IoC
>>>> container.
>>>>
>>>> No, I don't want to bundle Spring with Cayenne, besides it has to
>>>> integrate with the larger app ecosystem, so we still need to  
>>>> figure the
>>>> technical details. But the point is that we will be able to  
>>>> provide a single
>>>> place to configure all extension points, separate from the  
>>>> mapping. As
>>>> unlike the mapping those parameters are often different for the  
>>>> same
>>>> project, depending on the environment where it is deployed.
>>>>
>>>> Right now this place is cayenne.xml (and it might as well stay  
>>>> this way
>>>> in the future), just that unlike say Spring config files, it has  
>>>> a rigid
>>>> structure and is not generic enough to handle arbitrary  
>>>> extensions and
>>>> dependencies. It was ok for the early versions of Cayenne, since  
>>>> there was
>>>> only a few things you could change (data source factory and  
>>>> adapter I
>>>> believe). But now something more powerful and clean is desirable.
>>>>
>>>> Just some raw thoughts.
>>>>
>>>> Andrus
>>>
>>>
>>
>>
>


Re: IOC container

Posted by Malcolm Edgar <ma...@gmail.com>.
One concern I have about introducing a 3rd party IoC container is
class loader conflicts which may occur with including a popular IoC
container.  As Cayenne may have a dependency on version X but the
application uses version Y.

regards Malcolm Edgar

On Wed, Jun 3, 2009 at 6:03 AM, Andrus Adamchik <an...@objectstyle.org> wrote:
> I have a good opinion about Tapestry IoC approach in general (including the
> now defunct Hivemind), and I wanted to investigate Guice.
>
> There's some conflicting requirements to address here - we don't want to
> write/maintain our own IoC container, yet, we don't want to embed a huge
> third-party engine, of which we'll use only a subset of features. I'd like
> it to work standalone, as well as be able to integrate (or at least play
> well) with popular IoC containers (how many containers in one app is too
> many?). Then there's a matter of modeler support, which is adverse to
> annotations, and favors XML or other config files...
>
> All in all, I think assembling a core of Cayenne stack via such a container
> should open some interesting possibilities, beyond organizing current
> configuration.
>
> Andrus
>
>
>
> On Jun 2, 2009, at 6:53 PM, Robert Zeigler wrote:
>>
>> If you're really considering going the 3rd party ioc route, I highly
>> recommend T5IOC.
>> Note that configuration is (typically) done via code in T5IOC, but I find
>> it extremely flexible & powerful, while still being simple to use (and
>> small! :).
>> If not that, then guice. I'd even go for pico (though preferably not).
>>  Anything but the monster that spring has become. ;)
>>
>> Robert
>>
>> On Jun 2, 2009, at 6/29:02 AM , Andrus Adamchik wrote:
>>
>>>
>>> On Jun 2, 2009, at 4:38 PM, Andrus Adamchik wrote:
>>>
>>>>>
>>>>> Modeler support will be covered by setting class name of strategy
>>>>
>>>> I am afraid this approach will be rather arbitrary to the end user, so I
>>>> suggest we discuss it some more before putting it in Cayenne. Marking an
>>>> entity to use "soft delete" based on some criteria is a clear and
>>>> understandable feature. Setting a "delete strategy" is not, and will
>>>> contribute to confusion. This is totally be ok as a backend extension point,
>>>> but I will hate to see that as a general use feature.
>>>
>>> In this context let me mention one idea for Cayenne 3.0 + N, that I've
>>> been thinking about for some time. I am taking this to a separate thread to
>>> avoid distraction from the soft delete discussion, which has only tangential
>>> relevance.
>>>
>>> Since we already have a bunch of extension points throughout the stack,
>>> some exposed via the Modeler (misplaced like cache JGroups config, or
>>> justified like Adapter config), and some are available only via the code, we
>>> need a way to reign them in. The standard way of doing that is via an IoC
>>> container.
>>>
>>> No, I don't want to bundle Spring with Cayenne, besides it has to
>>> integrate with the larger app ecosystem, so we still need to figure the
>>> technical details. But the point is that we will be able to provide a single
>>> place to configure all extension points, separate from the mapping. As
>>> unlike the mapping those parameters are often different for the same
>>> project, depending on the environment where it is deployed.
>>>
>>> Right now this place is cayenne.xml (and it might as well stay this way
>>> in the future), just that unlike say Spring config files, it has a rigid
>>> structure and is not generic enough to handle arbitrary extensions and
>>> dependencies. It was ok for the early versions of Cayenne, since there was
>>> only a few things you could change (data source factory and adapter I
>>> believe). But now something more powerful and clean is desirable.
>>>
>>> Just some raw thoughts.
>>>
>>> Andrus
>>
>>
>
>

Re: IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
I have a good opinion about Tapestry IoC approach in general  
(including the now defunct Hivemind), and I wanted to investigate Guice.

There's some conflicting requirements to address here - we don't want  
to write/maintain our own IoC container, yet, we don't want to embed a  
huge third-party engine, of which we'll use only a subset of features.  
I'd like it to work standalone, as well as be able to integrate (or at  
least play well) with popular IoC containers (how many containers in  
one app is too many?). Then there's a matter of modeler support, which  
is adverse to annotations, and favors XML or other config files...

All in all, I think assembling a core of Cayenne stack via such a  
container should open some interesting possibilities, beyond  
organizing current configuration.

Andrus



On Jun 2, 2009, at 6:53 PM, Robert Zeigler wrote:
> If you're really considering going the 3rd party ioc route, I highly  
> recommend T5IOC.
> Note that configuration is (typically) done via code in T5IOC, but I  
> find it extremely flexible & powerful, while still being simple to  
> use (and small! :).
> If not that, then guice. I'd even go for pico (though preferably  
> not).  Anything but the monster that spring has become. ;)
>
> Robert
>
> On Jun 2, 2009, at 6/29:02 AM , Andrus Adamchik wrote:
>
>>
>> On Jun 2, 2009, at 4:38 PM, Andrus Adamchik wrote:
>>
>>>>
>>>> Modeler support will be covered by setting class name of strategy
>>>
>>> I am afraid this approach will be rather arbitrary to the end  
>>> user, so I suggest we discuss it some more before putting it in  
>>> Cayenne. Marking an entity to use "soft delete" based on some  
>>> criteria is a clear and understandable feature. Setting a "delete  
>>> strategy" is not, and will contribute to confusion. This is  
>>> totally be ok as a backend extension point, but I will hate to see  
>>> that as a general use feature.
>>
>> In this context let me mention one idea for Cayenne 3.0 + N, that  
>> I've been thinking about for some time. I am taking this to a  
>> separate thread to avoid distraction from the soft delete  
>> discussion, which has only tangential relevance.
>>
>> Since we already have a bunch of extension points throughout the  
>> stack, some exposed via the Modeler (misplaced like cache JGroups  
>> config, or justified like Adapter config), and some are available  
>> only via the code, we need a way to reign them in. The standard way  
>> of doing that is via an IoC container.
>>
>> No, I don't want to bundle Spring with Cayenne, besides it has to  
>> integrate with the larger app ecosystem, so we still need to figure  
>> the technical details. But the point is that we will be able to  
>> provide a single place to configure all extension points, separate  
>> from the mapping. As unlike the mapping those parameters are often  
>> different for the same project, depending on the environment where  
>> it is deployed.
>>
>> Right now this place is cayenne.xml (and it might as well stay this  
>> way in the future), just that unlike say Spring config files, it  
>> has a rigid structure and is not generic enough to handle arbitrary  
>> extensions and dependencies. It was ok for the early versions of  
>> Cayenne, since there was only a few things you could change (data  
>> source factory and adapter I believe). But now something more  
>> powerful and clean is desirable.
>>
>> Just some raw thoughts.
>>
>> Andrus
>
>


Re: IOC container

Posted by Robert Zeigler <ro...@roxanemy.com>.
If you're really considering going the 3rd party ioc route, I highly  
recommend T5IOC.
Note that configuration is (typically) done via code in T5IOC, but I  
find it extremely flexible & powerful, while still being simple to use  
(and small! :).
If not that, then guice. I'd even go for pico (though preferably  
not).  Anything but the monster that spring has become. ;)

Robert

On Jun 2, 2009, at 6/29:02 AM , Andrus Adamchik wrote:

>
> On Jun 2, 2009, at 4:38 PM, Andrus Adamchik wrote:
>
>>>
>>> Modeler support will be covered by setting class name of strategy
>>
>> I am afraid this approach will be rather arbitrary to the end user,  
>> so I suggest we discuss it some more before putting it in Cayenne.  
>> Marking an entity to use "soft delete" based on some criteria is a  
>> clear and understandable feature. Setting a "delete strategy" is  
>> not, and will contribute to confusion. This is totally be ok as a  
>> backend extension point, but I will hate to see that as a general  
>> use feature.
>
> In this context let me mention one idea for Cayenne 3.0 + N, that  
> I've been thinking about for some time. I am taking this to a  
> separate thread to avoid distraction from the soft delete  
> discussion, which has only tangential relevance.
>
> Since we already have a bunch of extension points throughout the  
> stack, some exposed via the Modeler (misplaced like cache JGroups  
> config, or justified like Adapter config), and some are available  
> only via the code, we need a way to reign them in. The standard way  
> of doing that is via an IoC container.
>
> No, I don't want to bundle Spring with Cayenne, besides it has to  
> integrate with the larger app ecosystem, so we still need to figure  
> the technical details. But the point is that we will be able to  
> provide a single place to configure all extension points, separate  
> from the mapping. As unlike the mapping those parameters are often  
> different for the same project, depending on the environment where  
> it is deployed.
>
> Right now this place is cayenne.xml (and it might as well stay this  
> way in the future), just that unlike say Spring config files, it has  
> a rigid structure and is not generic enough to handle arbitrary  
> extensions and dependencies. It was ok for the early versions of  
> Cayenne, since there was only a few things you could change (data  
> source factory and adapter I believe). But now something more  
> powerful and clean is desirable.
>
> Just some raw thoughts.
>
> Andrus


IOC container

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 2, 2009, at 4:38 PM, Andrus Adamchik wrote:

>>
>> Modeler support will be covered by setting class name of strategy
>
> I am afraid this approach will be rather arbitrary to the end user,  
> so I suggest we discuss it some more before putting it in Cayenne.  
> Marking an entity to use "soft delete" based on some criteria is a  
> clear and understandable feature. Setting a "delete strategy" is  
> not, and will contribute to confusion. This is totally be ok as a  
> backend extension point, but I will hate to see that as a general  
> use feature.

In this context let me mention one idea for Cayenne 3.0 + N, that I've  
been thinking about for some time. I am taking this to a separate  
thread to avoid distraction from the soft delete discussion, which has  
only tangential relevance.

Since we already have a bunch of extension points throughout the  
stack, some exposed via the Modeler (misplaced like cache JGroups  
config, or justified like Adapter config), and some are available only  
via the code, we need a way to reign them in. The standard way of  
doing that is via an IoC container.

No, I don't want to bundle Spring with Cayenne, besides it has to  
integrate with the larger app ecosystem, so we still need to figure  
the technical details. But the point is that we will be able to  
provide a single place to configure all extension points, separate  
from the mapping. As unlike the mapping those parameters are often  
different for the same project, depending on the environment where it  
is deployed.

Right now this place is cayenne.xml (and it might as well stay this  
way in the future), just that unlike say Spring config files, it has a  
rigid structure and is not generic enough to handle arbitrary  
extensions and dependencies. It was ok for the early versions of  
Cayenne, since there was only a few things you could change (data  
source factory and adapter I believe). But now something more powerful  
and clean is desirable.

Just some raw thoughts.

Andrus

Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
Seems we have same questions in second feature I wanted to implement -
qualifiers for DbEntities. Should they work for EJBQLs too? As far as I can
tell after looking at the code, current EJBQL doesn't use ObjEntity
qualifiers.
I can't think of anything better than implementing DbEntity qualifier as
simple string that will be ANDed with WHERE clauses for SELECT and JOIN
tables. This way we won't be able to handle any difference between different
DBMS. We just don't have "DB-based" expressions... Maybe you have better
ideas..?

Thanks,
Andrey

2009/6/3 Andrus Adamchik <an...@objectstyle.org>

>
> On Jun 3, 2009, at 4:12 PM, Andrey Razumovsky wrote:
>
>>
>>> Let's first decide which approach above we'll be using (1. intercept on
>>> commit or 2. intercept of anything "delete").
>>>
>>>
>> I see. What implemented now is "1.5 - intercept of anything
>> DeleteBatchQuery". This might be okay if we plan #2 someday. Actually I
>> want
>> this feature right now, and changing EJBQL nature might be tricky. So I
>> suggest we either end with #1 or commit current code, which is little part
>> of #2.
>>
>
> I suggest going with #1 then.
>
>
>  Looking at this one more time, I agree. This is irrelevant for approach
>>> #1,
>>> but for #2 I think we can achieve what we need with a DataNode bound
>>> SQLActionVisitor, which allows to process all types of queries in a
>>> generic
>>> fashion (see below my notes on EJBQL).
>>>
>>>
>> The most common SQLActionVisitor is JdbcActionBuilder and it cannot
>> contain
>> reference to DataNode by design, as said before.
>>
>
> I meant this in a general sense. Your strategy class can have an anonymous
> inner class implementing SQLActionVisitor or something like that. Anyways,
> this is not applicable for #1 ... I think.
>
> Andrus
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 3, 2009, at 4:12 PM, Andrey Razumovsky wrote:
>>
>> Let's first decide which approach above we'll be using (1.  
>> intercept on
>> commit or 2. intercept of anything "delete").
>>
>
> I see. What implemented now is "1.5 - intercept of anything
> DeleteBatchQuery". This might be okay if we plan #2 someday.  
> Actually I want
> this feature right now, and changing EJBQL nature might be tricky.  
> So I
> suggest we either end with #1 or commit current code, which is  
> little part
> of #2.

I suggest going with #1 then.


>> Looking at this one more time, I agree. This is irrelevant for  
>> approach #1,
>> but for #2 I think we can achieve what we need with a DataNode bound
>> SQLActionVisitor, which allows to process all types of queries in a  
>> generic
>> fashion (see below my notes on EJBQL).
>>
>
> The most common SQLActionVisitor is JdbcActionBuilder and it cannot  
> contain
> reference to DataNode by design, as said before.

I meant this in a general sense. Your strategy class can have an  
anonymous inner class implementing SQLActionVisitor or something like  
that. Anyways, this is not applicable for #1 ... I think.

Andrus

Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
>
>

>
> Let's first decide which approach above we'll be using (1. intercept on
> commit or 2. intercept of anything "delete").
>

I see. What implemented now is "1.5 - intercept of anything
DeleteBatchQuery". This might be okay if we plan #2 someday. Actually I want
this feature right now, and changing EJBQL nature might be tricky. So I
suggest we either end with #1 or commit current code, which is little part
of #2.


>
> Looking at this one more time, I agree. This is irrelevant for approach #1,
> but for #2 I think we can achieve what we need with a DataNode bound
> SQLActionVisitor, which allows to process all types of queries in a generic
> fashion (see below my notes on EJBQL).
>

The most common SQLActionVisitor is JdbcActionBuilder and it cannot contain
reference to DataNode by design, as said before. I should say that uploaded
"DN bounded OperationObserver" allows to pass DN to ALL queries.
"Processing" e.g. ebjql and batch in generic fashion currently seems
imposible to me :(. They can logically do the same, but implementation is
too different.

As I already said, both long-plan ways are OK for me, but I wish to be able
to intercept context commit action as fast as possible.

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 3, 2009, at 3:00 PM, Andrey Razumovsky wrote:

> First, the main goal of the feature is to provide extension point for
> insert/update/delete queries of context commit process.

This is what I thought initially. But you mentioning intercepting  
delete queries at the lower levels made me think your intent was to  
make things more generic, and rewrite every single delete going  
through the system irregardless of origin?

In any event, both approaches do make sense. The first one is ok short  
term (3.0). The second one - long term, considering that we want any  
batch delete queries, except maybe SQLTemplate and ProcedureQuery, to  
change the state of objects in the context, which we are not doing  
now, "performQuery" becomes sort of like "commitChanges". Right now we  
need to pick one approach for 3.0, and follow it consistently.

> Currently *BatchQueries are responsible for those actions. But they  
> can be used
> separately. Should we keep original batch queries (e.g. if they are  
> invoked
> in context.performQuery()) work as they did, ignoring user-provided
> 'strategy'? Who knows. If so, we need to create different types of  
> queries
> in DDFlushAction. Current implementation says "no". I can stand both  
> ways.

Let's first decide which approach above we'll be using (1. intercept  
on commit or 2. intercept of anything "delete").

> Second, where should user-provided code be attached? Certainly, not  
> to a
> datamap, as we discussed before. And not to DbAdapter. DbAdapter was
> designed to handle differences between DBMS and we definitely want
> user-provided behaviour act on all DBMS. So that should be DD or DN
> (data-node). As an example, there is new SchemaUpdateStrategy which  
> in some
> other way specifies how Cayenne should affect on DB. It is DN  
> property.

Looking at this one more time, I agree. This is irrelevant for  
approach #1, but for #2 I think we can achieve what we need with a  
DataNode bound SQLActionVisitor, which allows to process all types of  
queries in a generic fashion (see below my notes on EJBQL).

> Third, should we push this behavior to other actions, e.g. EJBQL? I  
> don't
> think so. EJBQL is same as SQL(Template) but in terms of object  
> language (as
> far as I know, it works through SQLTemplate). So it's more "raw" than
> context's actions.

That's the thing - EJBQL, for all its similarity to SQLTemplate, is  
not "raw". We don't have lots of usable object API around it yet, but  
it is as OO as SelectQuery or a BatchQuery. It can be unambiguously  
"compiled" back into a tree of mapping objects. So if we go with  
strategy 2, DeleteBatchQuery and deleting EJBQL are the same beasts.

> Fourth, how should we pass the strategy to the place where query  
> actions are
> performed? This is tricky implementation problem. If we create  
> separate
> queries for "batches with user behavior", it'll be simple. Currently  
> it
> works, although code seems not very clear to me.

Let's first decide which approach above we'll be using, and then  
discuss this.

Andrus


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
I'm a bit confused here. Let's try to make it clear.

First, the main goal of the feature is to provide extension point for
insert/update/delete queries of context commit process. Currently
*BatchQueries are responsible for those actions. But they can be used
separately. Should we keep original batch queries (e.g. if they are invoked
in context.performQuery()) work as they did, ignoring user-provided
'strategy'? Who knows. If so, we need to create different types of queries
in DDFlushAction. Current implementation says "no". I can stand both ways.

Second, where should user-provided code be attached? Certainly, not to a
datamap, as we discussed before. And not to DbAdapter. DbAdapter was
designed to handle differences between DBMS and we definitely want
user-provided behaviour act on all DBMS. So that should be DD or DN
(data-node). As an example, there is new SchemaUpdateStrategy which in some
other way specifies how Cayenne should affect on DB. It is DN property.

Third, should we push this behavior to other actions, e.g. EJBQL? I don't
think so. EJBQL is same as SQL(Template) but in terms of object language (as
far as I know, it works through SQLTemplate). So it's more "raw" than
context's actions.

Fourth, how should we pass the strategy to the place where query actions are
performed? This is tricky implementation problem. If we create separate
queries for "batches with user behavior", it'll be simple. Currently it
works, although code seems not very clear to me.

2009/6/3 Andrus Adamchik <an...@objectstyle.org>

> Sorry for jumping the gun. Let me take it back for a moment. I was still
> trying to understand how do we present this feature to a user, and where it
> fits in the overall design. Now after this discussion, I am clear on the
> intention (I think), and more comfortable with the suggested concept and
> implementation.
>
> So intercepting things at the DataNode level is ok. I am +1 on that.
>
> One more question (you've probably thought it through already). The
> existing extension point for changing low level query behavior is
> DbAdapter.getAction(Query query, DataNode node). Should we build on that
> instead of adding another strategy to the DataNode? This seems particularly
> promising, since there is also a very common batch delete/update query -
> EJBQLQuery, that we'd need to handle. SQLAction overriding can apply to any
> kind of query.
>
> Thoughts?
> Andrus
>
>
>
> On Jun 3, 2009, at 1:36 PM, Andrus Adamchik wrote:
>
>> On Jun 3, 2009, at 12:01 PM, Andrey Razumovsky wrote:
>>
>>  I've never used that myself, but e.g. DeleteBatchQuery can be fired
>>> separately using context.performAction(..). It is public in .query
>>> package
>>> after all. I don't want to have different behaviors for that
>>>
>>
>> I disagree. I think we do want delete query to behave like delete query,
>> and use the soft delete strategy for the objects managed by the context.
>>
>> Andrus
>>
>
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
Sorry for jumping the gun. Let me take it back for a moment. I was  
still trying to understand how do we present this feature to a user,  
and where it fits in the overall design. Now after this discussion, I  
am clear on the intention (I think), and more comfortable with the  
suggested concept and implementation.

So intercepting things at the DataNode level is ok. I am +1 on that.

One more question (you've probably thought it through already). The  
existing extension point for changing low level query behavior is  
DbAdapter.getAction(Query query, DataNode node). Should we build on  
that instead of adding another strategy to the DataNode? This seems  
particularly promising, since there is also a very common batch delete/ 
update query - EJBQLQuery, that we'd need to handle. SQLAction  
overriding can apply to any kind of query.

Thoughts?
Andrus


On Jun 3, 2009, at 1:36 PM, Andrus Adamchik wrote:
> On Jun 3, 2009, at 12:01 PM, Andrey Razumovsky wrote:
>
>> I've never used that myself, but e.g. DeleteBatchQuery can be fired
>> separately using context.performAction(..). It is public in .query  
>> package
>> after all. I don't want to have different behaviors for that
>
> I disagree. I think we do want delete query to behave like delete  
> query, and use the soft delete strategy for the objects managed by  
> the context.
>
> Andrus


Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 3, 2009, at 12:01 PM, Andrey Razumovsky wrote:

> I've never used that myself, but e.g. DeleteBatchQuery can be fired
> separately using context.performAction(..). It is public in .query  
> package
> after all. I don't want to have different behaviors for that

I disagree. I think we do want delete query to behave like delete  
query, and use the soft delete strategy for the objects managed by the  
context.

Andrus


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
I've never used that myself, but e.g. DeleteBatchQuery can be fired
separately using context.performAction(..). It is public in .query package
after all. I don't want to have different behaviors for that

2009/6/3 Andrus Adamchik <an...@objectstyle.org>

> Let me rephrase. What other cases do we want to handle with this strategy,
> in addition to "commit" (that triggers flush action)?
>
> Andrus
>
>
>
> On Jun 3, 2009, at 11:51 AM, Andrus Adamchik wrote:
>
>> On Jun 3, 2009, at 11:45 AM, Andrey Razumovsky wrote:
>>
>>  Yes, but that will make factory working only in flush action, but not if
>>> it
>>> is fired from somewhere else.
>>>
>>
>> Correct. But why do we want to do it differently?
>>
>> Andrus
>>
>>
>>
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
Let me rephrase. What other cases do we want to handle with this  
strategy, in addition to "commit" (that triggers flush action)?

Andrus


On Jun 3, 2009, at 11:51 AM, Andrus Adamchik wrote:
> On Jun 3, 2009, at 11:45 AM, Andrey Razumovsky wrote:
>
>> Yes, but that will make factory working only in flush action, but  
>> not if it
>> is fired from somewhere else.
>
> Correct. But why do we want to do it differently?
>
> Andrus
>
>


Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 3, 2009, at 11:45 AM, Andrey Razumovsky wrote:

> Yes, but that will make factory working only in flush action, but  
> not if it
> is fired from somewhere else.

Correct. But why do we want to do it differently?

Andrus


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
Yes, but that will make factory working only in flush action, but not if it
is fired from somewhere else. I've uploaded what I have now. Passing of node
is a quite blurry, but I can stand this solution

2009/6/3 Andrus Adamchik <an...@objectstyle.org>

>
> On Jun 3, 2009, at 11:24 AM, Andrus Adamchik wrote:
>
>   You'd generate a BatchUpdateAction instead of delete or something like
>> that.
>>
>
> I mean a BatchUpdateQuery not Action.
>
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 3, 2009, at 11:24 AM, Andrus Adamchik wrote:

>  You'd generate a BatchUpdateAction instead of delete or something  
> like that.

I mean a BatchUpdateQuery not Action.


Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
>  After all, batch queries are public and can
> be fired from anywhere, including context.performQuery(..).

Exactly, BatchQuery is just that - a query. And we probably do not  
want to redefine how it is processed. So this leads me to think that  
the logic fork should still happen somewhere inside  
DataDomainFlushAction. You'd generate a BatchUpdateAction instead of  
delete or something like that.

Andrus


On Jun 3, 2009, at 11:16 AM, Andrey Razumovsky wrote:

> It's not that easy as it sounds. BatchAction is born from BatchQuery  
> (which
> is in .query package and does not have access to DataDomain/Node) and
> JDBCActionBuilder (which is logical part of JdbcAdapter, and also  
> does not
> have access to DataDomain/Node). After all, batch queries are public  
> and can
> be fired from anywhere, including context.performQuery(..). So it  
> starts not
> with DataDomainFlushAction, but with DataNodeQueryAction. The best I  
> could
> do was adding factory property to DataNode and passing it to action  
> in query
> observer.
>
> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>
>> I swiched to DataMap after I saw no quick access to DataDomain in
>>> BatchAction class.
>>>
>>
>> It all starts with DataDomainFlushAction, which has a reference to  
>> DD, so
>> there should be a way to inject factory down the tree.
>>
>> I assume API changes in public classes of access.jdbc package are  
>> allowed?
>>>
>>
>> Until we are in Beta, yes.
>>
>> Andrus
>>
>>
>>
>> On Jun 2, 2009, at 5:25 PM, Andrey Razumovsky wrote:
>>
>> I swiched to DataMap after I saw no quick access to DataDomain in
>>> BatchAction class. This needs futher investigation, we need to  
>>> pass domain
>>> there somehow. I assume API changes in public classes of access.jdbc
>>> package
>>> are allowed?
>>>
>>> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>>>
>>> Excellent. I have one comment (consistent with my position in the
>>>> previous
>>>> message). Configuration of the factory below should be attached  
>>>> to the
>>>> stack
>>>> objects (e.g. DataDomain), not the mapping objects (DataMap):
>>>>
>>>> +
>>>> +    /**
>>>> +     * Sets factory for creating QueryBuilders
>>>> +     */
>>>> +    public void setQueryBuilderFactory(BatchQueryBuilderFactory
>>>> queryBuilderFactory) {
>>>> +        this.queryBuilderFactory = queryBuilderFactory;
>>>> +    }
>>>> +
>>>> +    /**
>>>> +     * @return factory for creating QueryBuilders. Might be null
>>>> +     */
>>>> +    public BatchQueryBuilderFactory getQueryBuilderFactory() {
>>>> +        return queryBuilderFactory;
>>>> +    }
>>>>
>>>> Cheers,
>>>> Andrus
>>>>
>>>> P.S. Maybe you can separately commit the @Deprecated part of the  
>>>> patch
>>>> ;-)
>>>>
>>>>
>>>>
>>>> On Jun 2, 2009, at 5:07 PM, Andrey Razumovsky wrote:
>>>>
>>>> For not to be unsubstantiated, I uploaded my vision of the  
>>>> feature. Note
>>>>
>>>>> that there is no modeler support. It allows to provide custom  
>>>>> factory
>>>>> that
>>>>> creates builders of INSERT, UPDATE, DELETE queries. 'Soft-delete'
>>>>> factory
>>>>> is
>>>>> included.
>>>>> I do not say that 'soft delete' checkbox is not needed, but  
>>>>> uploaded
>>>>> code
>>>>> is
>>>>> much more generic and allows to plug any behavior (maybe even  
>>>>> Ari's
>>>>> proposed
>>>>> 'versions'). 'Soft' strategy can be configured with 'deleted'  
>>>>> field name
>>>>> and
>>>>> will not fire UPDATE if such field does not exist in DB table.
>>>>>
>>>>> Please add your comments!
>>>>>
>>>>> Thanks,
>>>>> Andrey
>>>>>
>>>>> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>>>>>
>>>>>
>>>>> On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:
>>>>>>
>>>>>> But I'm no fan of adding some sort of 'soft' checkbox for  
>>>>>> dbattributes
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> I was suggesting marking entity with a "soft delete" checkbox  
>>>>>>> (not
>>>>>> individual attribute - this would make no sense), and creating a
>>>>>> criteria
>>>>>> based on qualifier that references an attribute.
>>>>>>
>>>>>> Modeler support will be covered by setting class name of strategy
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> I am afraid this approach will be rather arbitrary to the end  
>>>>>>> user,
>>>>>> so I
>>>>>> suggest we discuss it some more before putting it in Cayenne.  
>>>>>> Marking
>>>>>> an
>>>>>> entity to use "soft delete" based on some criteria is a clear and
>>>>>> understandable feature. Setting a "delete strategy" is not, and  
>>>>>> will
>>>>>> contribute to confusion. This is totally be ok as a backend  
>>>>>> extension
>>>>>> point,
>>>>>> but I will hate to see that as a general use feature.
>>>>>>
>>>>>> Andrus
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>
>>


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
It's not that easy as it sounds. BatchAction is born from BatchQuery (which
is in .query package and does not have access to DataDomain/Node) and
JDBCActionBuilder (which is logical part of JdbcAdapter, and also does not
have access to DataDomain/Node). After all, batch queries are public and can
be fired from anywhere, including context.performQuery(..). So it starts not
with DataDomainFlushAction, but with DataNodeQueryAction. The best I could
do was adding factory property to DataNode and passing it to action in query
observer.

2009/6/2 Andrus Adamchik <an...@objectstyle.org>

> I swiched to DataMap after I saw no quick access to DataDomain in
>> BatchAction class.
>>
>
> It all starts with DataDomainFlushAction, which has a reference to DD, so
> there should be a way to inject factory down the tree.
>
>  I assume API changes in public classes of access.jdbc package are allowed?
>>
>
> Until we are in Beta, yes.
>
> Andrus
>
>
>
> On Jun 2, 2009, at 5:25 PM, Andrey Razumovsky wrote:
>
>  I swiched to DataMap after I saw no quick access to DataDomain in
>> BatchAction class. This needs futher investigation, we need to pass domain
>> there somehow. I assume API changes in public classes of access.jdbc
>> package
>> are allowed?
>>
>> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>>
>>  Excellent. I have one comment (consistent with my position in the
>>> previous
>>> message). Configuration of the factory below should be attached to the
>>> stack
>>> objects (e.g. DataDomain), not the mapping objects (DataMap):
>>>
>>> +
>>> +    /**
>>> +     * Sets factory for creating QueryBuilders
>>> +     */
>>> +    public void setQueryBuilderFactory(BatchQueryBuilderFactory
>>> queryBuilderFactory) {
>>> +        this.queryBuilderFactory = queryBuilderFactory;
>>> +    }
>>> +
>>> +    /**
>>> +     * @return factory for creating QueryBuilders. Might be null
>>> +     */
>>> +    public BatchQueryBuilderFactory getQueryBuilderFactory() {
>>> +        return queryBuilderFactory;
>>> +    }
>>>
>>> Cheers,
>>> Andrus
>>>
>>> P.S. Maybe you can separately commit the @Deprecated part of the patch
>>> ;-)
>>>
>>>
>>>
>>> On Jun 2, 2009, at 5:07 PM, Andrey Razumovsky wrote:
>>>
>>> For not to be unsubstantiated, I uploaded my vision of the feature. Note
>>>
>>>> that there is no modeler support. It allows to provide custom factory
>>>> that
>>>> creates builders of INSERT, UPDATE, DELETE queries. 'Soft-delete'
>>>> factory
>>>> is
>>>> included.
>>>> I do not say that 'soft delete' checkbox is not needed, but uploaded
>>>> code
>>>> is
>>>> much more generic and allows to plug any behavior (maybe even Ari's
>>>> proposed
>>>> 'versions'). 'Soft' strategy can be configured with 'deleted' field name
>>>> and
>>>> will not fire UPDATE if such field does not exist in DB table.
>>>>
>>>> Please add your comments!
>>>>
>>>> Thanks,
>>>> Andrey
>>>>
>>>> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>>>>
>>>>
>>>>  On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:
>>>>>
>>>>> But I'm no fan of adding some sort of 'soft' checkbox for dbattributes
>>>>>
>>>>>
>>>>>>
>>>>>>  I was suggesting marking entity with a "soft delete" checkbox (not
>>>>> individual attribute - this would make no sense), and creating a
>>>>> criteria
>>>>> based on qualifier that references an attribute.
>>>>>
>>>>> Modeler support will be covered by setting class name of strategy
>>>>>
>>>>>
>>>>>>
>>>>>>  I am afraid this approach will be rather arbitrary to the end user,
>>>>> so I
>>>>> suggest we discuss it some more before putting it in Cayenne. Marking
>>>>> an
>>>>> entity to use "soft delete" based on some criteria is a clear and
>>>>> understandable feature. Setting a "delete strategy" is not, and will
>>>>> contribute to confusion. This is totally be ok as a backend extension
>>>>> point,
>>>>> but I will hate to see that as a general use feature.
>>>>>
>>>>> Andrus
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
> I swiched to DataMap after I saw no quick access to DataDomain in
> BatchAction class.

It all starts with DataDomainFlushAction, which has a reference to DD,  
so there should be a way to inject factory down the tree.

> I assume API changes in public classes of access.jdbc package are  
> allowed?

Until we are in Beta, yes.

Andrus


On Jun 2, 2009, at 5:25 PM, Andrey Razumovsky wrote:

> I swiched to DataMap after I saw no quick access to DataDomain in
> BatchAction class. This needs futher investigation, we need to pass  
> domain
> there somehow. I assume API changes in public classes of access.jdbc  
> package
> are allowed?
>
> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>
>> Excellent. I have one comment (consistent with my position in the  
>> previous
>> message). Configuration of the factory below should be attached to  
>> the stack
>> objects (e.g. DataDomain), not the mapping objects (DataMap):
>>
>> +
>> +    /**
>> +     * Sets factory for creating QueryBuilders
>> +     */
>> +    public void setQueryBuilderFactory(BatchQueryBuilderFactory
>> queryBuilderFactory) {
>> +        this.queryBuilderFactory = queryBuilderFactory;
>> +    }
>> +
>> +    /**
>> +     * @return factory for creating QueryBuilders. Might be null
>> +     */
>> +    public BatchQueryBuilderFactory getQueryBuilderFactory() {
>> +        return queryBuilderFactory;
>> +    }
>>
>> Cheers,
>> Andrus
>>
>> P.S. Maybe you can separately commit the @Deprecated part of the  
>> patch ;-)
>>
>>
>>
>> On Jun 2, 2009, at 5:07 PM, Andrey Razumovsky wrote:
>>
>> For not to be unsubstantiated, I uploaded my vision of the feature.  
>> Note
>>> that there is no modeler support. It allows to provide custom  
>>> factory that
>>> creates builders of INSERT, UPDATE, DELETE queries. 'Soft-delete'  
>>> factory
>>> is
>>> included.
>>> I do not say that 'soft delete' checkbox is not needed, but  
>>> uploaded code
>>> is
>>> much more generic and allows to plug any behavior (maybe even Ari's
>>> proposed
>>> 'versions'). 'Soft' strategy can be configured with 'deleted'  
>>> field name
>>> and
>>> will not fire UPDATE if such field does not exist in DB table.
>>>
>>> Please add your comments!
>>>
>>> Thanks,
>>> Andrey
>>>
>>> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>>>
>>>
>>>> On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:
>>>>
>>>> But I'm no fan of adding some sort of 'soft' checkbox for  
>>>> dbattributes
>>>>
>>>>>
>>>>>
>>>> I was suggesting marking entity with a "soft delete" checkbox (not
>>>> individual attribute - this would make no sense), and creating a  
>>>> criteria
>>>> based on qualifier that references an attribute.
>>>>
>>>> Modeler support will be covered by setting class name of strategy
>>>>
>>>>>
>>>>>
>>>> I am afraid this approach will be rather arbitrary to the end  
>>>> user, so I
>>>> suggest we discuss it some more before putting it in Cayenne.  
>>>> Marking an
>>>> entity to use "soft delete" based on some criteria is a clear and
>>>> understandable feature. Setting a "delete strategy" is not, and  
>>>> will
>>>> contribute to confusion. This is totally be ok as a backend  
>>>> extension
>>>> point,
>>>> but I will hate to see that as a general use feature.
>>>>
>>>> Andrus
>>>>
>>>>
>>>>
>>>>
>>


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
I swiched to DataMap after I saw no quick access to DataDomain in
BatchAction class. This needs futher investigation, we need to pass domain
there somehow. I assume API changes in public classes of access.jdbc package
are allowed?

2009/6/2 Andrus Adamchik <an...@objectstyle.org>

> Excellent. I have one comment (consistent with my position in the previous
> message). Configuration of the factory below should be attached to the stack
> objects (e.g. DataDomain), not the mapping objects (DataMap):
>
> +
> +    /**
> +     * Sets factory for creating QueryBuilders
> +     */
> +    public void setQueryBuilderFactory(BatchQueryBuilderFactory
> queryBuilderFactory) {
> +        this.queryBuilderFactory = queryBuilderFactory;
> +    }
> +
> +    /**
> +     * @return factory for creating QueryBuilders. Might be null
> +     */
> +    public BatchQueryBuilderFactory getQueryBuilderFactory() {
> +        return queryBuilderFactory;
> +    }
>
> Cheers,
> Andrus
>
> P.S. Maybe you can separately commit the @Deprecated part of the patch ;-)
>
>
>
> On Jun 2, 2009, at 5:07 PM, Andrey Razumovsky wrote:
>
>  For not to be unsubstantiated, I uploaded my vision of the feature. Note
>> that there is no modeler support. It allows to provide custom factory that
>> creates builders of INSERT, UPDATE, DELETE queries. 'Soft-delete' factory
>> is
>> included.
>> I do not say that 'soft delete' checkbox is not needed, but uploaded code
>> is
>> much more generic and allows to plug any behavior (maybe even Ari's
>> proposed
>> 'versions'). 'Soft' strategy can be configured with 'deleted' field name
>> and
>> will not fire UPDATE if such field does not exist in DB table.
>>
>> Please add your comments!
>>
>> Thanks,
>> Andrey
>>
>> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>>
>>
>>> On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:
>>>
>>> But I'm no fan of adding some sort of 'soft' checkbox for dbattributes
>>>
>>>>
>>>>
>>> I was suggesting marking entity with a "soft delete" checkbox (not
>>> individual attribute - this would make no sense), and creating a criteria
>>> based on qualifier that references an attribute.
>>>
>>> Modeler support will be covered by setting class name of strategy
>>>
>>>>
>>>>
>>> I am afraid this approach will be rather arbitrary to the end user, so I
>>> suggest we discuss it some more before putting it in Cayenne. Marking an
>>> entity to use "soft delete" based on some criteria is a clear and
>>> understandable feature. Setting a "delete strategy" is not, and will
>>> contribute to confusion. This is totally be ok as a backend extension
>>> point,
>>> but I will hate to see that as a general use feature.
>>>
>>> Andrus
>>>
>>>
>>>
>>>
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
Excellent. I have one comment (consistent with my position in the  
previous message). Configuration of the factory below should be  
attached to the stack objects (e.g. DataDomain), not the mapping  
objects (DataMap):

+
+    /**
+     * Sets factory for creating QueryBuilders
+     */
+    public void setQueryBuilderFactory(BatchQueryBuilderFactory  
queryBuilderFactory) {
+        this.queryBuilderFactory = queryBuilderFactory;
+    }
+
+    /**
+     * @return factory for creating QueryBuilders. Might be null
+     */
+    public BatchQueryBuilderFactory getQueryBuilderFactory() {
+        return queryBuilderFactory;
+    }

Cheers,
Andrus

P.S. Maybe you can separately commit the @Deprecated part of the  
patch ;-)


On Jun 2, 2009, at 5:07 PM, Andrey Razumovsky wrote:

> For not to be unsubstantiated, I uploaded my vision of the feature.  
> Note
> that there is no modeler support. It allows to provide custom  
> factory that
> creates builders of INSERT, UPDATE, DELETE queries. 'Soft-delete'  
> factory is
> included.
> I do not say that 'soft delete' checkbox is not needed, but uploaded  
> code is
> much more generic and allows to plug any behavior (maybe even Ari's  
> proposed
> 'versions'). 'Soft' strategy can be configured with 'deleted' field  
> name and
> will not fire UPDATE if such field does not exist in DB table.
>
> Please add your comments!
>
> Thanks,
> Andrey
>
> 2009/6/2 Andrus Adamchik <an...@objectstyle.org>
>
>>
>> On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:
>>
>> But I'm no fan of adding some sort of 'soft' checkbox for  
>> dbattributes
>>>
>>
>> I was suggesting marking entity with a "soft delete" checkbox (not
>> individual attribute - this would make no sense), and creating a  
>> criteria
>> based on qualifier that references an attribute.
>>
>> Modeler support will be covered by setting class name of strategy
>>>
>>
>> I am afraid this approach will be rather arbitrary to the end user,  
>> so I
>> suggest we discuss it some more before putting it in Cayenne.  
>> Marking an
>> entity to use "soft delete" based on some criteria is a clear and
>> understandable feature. Setting a "delete strategy" is not, and will
>> contribute to confusion. This is totally be ok as a backend  
>> extension point,
>> but I will hate to see that as a general use feature.
>>
>> Andrus
>>
>>
>>


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
For not to be unsubstantiated, I uploaded my vision of the feature. Note
that there is no modeler support. It allows to provide custom factory that
creates builders of INSERT, UPDATE, DELETE queries. 'Soft-delete' factory is
included.
I do not say that 'soft delete' checkbox is not needed, but uploaded code is
much more generic and allows to plug any behavior (maybe even Ari's proposed
'versions'). 'Soft' strategy can be configured with 'deleted' field name and
will not fire UPDATE if such field does not exist in DB table.

Please add your comments!

Thanks,
Andrey

2009/6/2 Andrus Adamchik <an...@objectstyle.org>

>
> On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:
>
>  But I'm no fan of adding some sort of 'soft' checkbox for dbattributes
>>
>
> I was suggesting marking entity with a "soft delete" checkbox (not
> individual attribute - this would make no sense), and creating a criteria
> based on qualifier that references an attribute.
>
>  Modeler support will be covered by setting class name of strategy
>>
>
> I am afraid this approach will be rather arbitrary to the end user, so I
> suggest we discuss it some more before putting it in Cayenne. Marking an
> entity to use "soft delete" based on some criteria is a clear and
> understandable feature. Setting a "delete strategy" is not, and will
> contribute to confusion. This is totally be ok as a backend extension point,
> but I will hate to see that as a general use feature.
>
> Andrus
>
>
>

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 2, 2009, at 2:54 PM, Andrey Razumovsky wrote:

> But I'm no fan of adding some sort of 'soft' checkbox for dbattributes

I was suggesting marking entity with a "soft delete" checkbox (not  
individual attribute - this would make no sense), and creating a  
criteria based on qualifier that references an attribute.

> Modeler support will be covered by setting class name of strategy

I am afraid this approach will be rather arbitrary to the end user, so  
I suggest we discuss it some more before putting it in Cayenne.  
Marking an entity to use "soft delete" based on some criteria is a  
clear and understandable feature. Setting a "delete strategy" is not,  
and will contribute to confusion. This is totally be ok as a backend  
extension point, but I will hate to see that as a general use feature.

Andrus



Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
I plan to add some default 'soft' strategy for everyone to use, and it will
likely have name of 'deleted' field as constructor parameter. But I'm no fan
of adding some sort of 'soft' checkbox for dbattributes, because it will
make new problems, such as handling several soft attributes and so on. This
is quite a rare case, after all. Modeler support will be covered by setting
class name of strategy

2009/6/2 Aristedes Maniatis <ar...@ish.com.au>

>
> On 02/06/2009, at 8:08 PM, Andrus Adamchik wrote:
>
>
>> On Jun 2, 2009, at 12:29 PM, Aristedes Maniatis wrote:
>>
>>
>>> 1. Because the second most commonly used implementation will be:
>>>
>>> * boolean NOT NULL field called 'isDeleted'
>>>
>>> Could this alternative implementation be one of the 'out of the box'
>>> choices? For us, we'd want that choice per table since some tables we
>>> actually do delete (since we don't care about keeping historical data). For
>>> Cayenne, the ability to do this without too much code would be very useful
>>> and a strong 'selling point' for the framework.
>>>
>>
>> (BTW we have another area where we could provide a sensible default - the
>> auto increment version column.)
>>
>> What I would like to avoid is implicit invisible mappings forcing user
>> into Cayenne table/column naming conventions. The ability to work on top of
>> an (almost) arbitrary schema is a big deal in the database world. Cayenne
>> never had any such conventions (ok, except for AUTO_PK_TABLE), and this was
>> also a strong usability point.
>>
>> Fortunately we have the Modeler, so we can achieve the best of both
>> worlds. The modeler can create a needed column and a qualifier if an entity
>> is marked as "soft delete". The user can stick with those, or go and edit
>> the names.
>>
>
>
> For sure. I think Andrey wants to implement a generic hook so that the
> entire implementation of what 'delete' means can be replaced by an alternate
> strategy almost like specifying a lifecycle listener. That sounds really
> complex for a user to implement, but some baked-in strategies would be
> useful. You would still get to choose which column represents the concept of
> 'deleted', just as you currently choose which column is the inheritance
> discriminator in the superclass dbEntity.
>
>
> Ari
>
>
>
> -------------------------->
> ish
> http://www.ish.com.au
> Level 1, 30 Wilson Street Newtown 2042 Australia
> phone +61 2 9550 5001   fax +61 2 9550 4001
> GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A
>
>
>

Re: Non-physical delete... again

Posted by Aristedes Maniatis <ar...@ish.com.au>.
On 02/06/2009, at 8:08 PM, Andrus Adamchik wrote:

>
> On Jun 2, 2009, at 12:29 PM, Aristedes Maniatis wrote:
>
>>
>> 1. Because the second most commonly used implementation will be:
>>
>> * boolean NOT NULL field called 'isDeleted'
>>
>> Could this alternative implementation be one of the 'out of the  
>> box' choices? For us, we'd want that choice per table since some  
>> tables we actually do delete (since we don't care about keeping  
>> historical data). For Cayenne, the ability to do this without too  
>> much code would be very useful and a strong 'selling point' for the  
>> framework.
>
> (BTW we have another area where we could provide a sensible default  
> - the auto increment version column.)
>
> What I would like to avoid is implicit invisible mappings forcing  
> user into Cayenne table/column naming conventions. The ability to  
> work on top of an (almost) arbitrary schema is a big deal in the  
> database world. Cayenne never had any such conventions (ok, except  
> for AUTO_PK_TABLE), and this was also a strong usability point.
>
> Fortunately we have the Modeler, so we can achieve the best of both  
> worlds. The modeler can create a needed column and a qualifier if an  
> entity is marked as "soft delete". The user can stick with those, or  
> go and edit the names.


For sure. I think Andrey wants to implement a generic hook so that the  
entire implementation of what 'delete' means can be replaced by an  
alternate strategy almost like specifying a lifecycle listener. That  
sounds really complex for a user to implement, but some baked-in  
strategies would be useful. You would still get to choose which column  
represents the concept of 'deleted', just as you currently choose  
which column is the inheritance discriminator in the superclass  
dbEntity.

Ari



-------------------------->
ish
http://www.ish.com.au
Level 1, 30 Wilson Street Newtown 2042 Australia
phone +61 2 9550 5001   fax +61 2 9550 4001
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A



Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 2, 2009, at 12:29 PM, Aristedes Maniatis wrote:

>
> 1. Because the second most commonly used implementation will be:
>
> * boolean NOT NULL field called 'isDeleted'
>
> Could this alternative implementation be one of the 'out of the box'  
> choices? For us, we'd want that choice per table since some tables  
> we actually do delete (since we don't care about keeping historical  
> data). For Cayenne, the ability to do this without too much code  
> would be very useful and a strong 'selling point' for the framework.

(BTW we have another area where we could provide a sensible default -  
the auto increment version column.)

What I would like to avoid is implicit invisible mappings forcing user  
into Cayenne table/column naming conventions. The ability to work on  
top of an (almost) arbitrary schema is a big deal in the database  
world. Cayenne never had any such conventions (ok, except for  
AUTO_PK_TABLE), and this was also a strong usability point.

Fortunately we have the Modeler, so we can achieve the best of both  
worlds. The modeler can create a needed column and a qualifier if an  
entity is marked as "soft delete". The user can stick with those, or  
go and edit the names.

Andrus

Re: Non-physical delete... again

Posted by Aristedes Maniatis <ar...@ish.com.au>.
On 02/06/2009, at 7:08 PM, Andrey Razumovsky wrote:

>> Yeah, good idea to move this down the stack. I would love to have the
>> ObjectContext level code to stay unchanged, but then generate  
>> UPDATE instead
>> of DELETE at the lower levels if entity is tagged as "soft delete".
>
>
> I actually want to see this more generic, i.e. DeletionStrategy  
> interface
> with one default implementation (which fires DELETE) and ability to  
> set my
> own.



Two thoughts:

1. Because the second most commonly used implementation will be:

* boolean NOT NULL field called 'isDeleted'

Could this alternative implementation be one of the 'out of the box'  
choices? For us, we'd want that choice per table since some tables we  
actually do delete (since we don't care about keeping historical  
data). For Cayenne, the ability to do this without too much code would  
be very useful and a strong 'selling point' for the framework.



2. This is only a step from having an update strategy as well. For  
instance, a customer who wanted to keep a complete audit trail of all  
changes to Contact records might want every UPDATE to actually be an  
INSERT with the old record marked as deleted and all relations  
appropriately adjusted. I'm not convinced this is the best design  
pattern (as opposed to storing the diffs of the changes in some log  
file), but I've been thinking a little about this approach.




Ari


-------------------------->
ish
http://www.ish.com.au
Level 1, 30 Wilson Street Newtown 2042 Australia
phone +61 2 9550 5001   fax +61 2 9550 4001
GPG fingerprint CBFB 84B4 738D 4E87 5E5C  5EFA EF6A 7D2E 3E49 102A



Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 2, 2009, at 12:08 PM, Andrey Razumovsky wrote:

>>>
>>> 2.  Deletion strategy for DataDomain. This means I do not always  
>>> fire
>>> DeleteAction, but maybe something else (update action in my case).
>>>
>>
>> Yeah, good idea to move this down the stack. I would love to have the
>> ObjectContext level code to stay unchanged, but then generate  
>> UPDATE instead
>> of DELETE at the lower levels if entity is tagged as "soft delete".
>
>
> I actually want to see this more generic, i.e. DeletionStrategy  
> interface
> with one default implementation (which fires DELETE) and ability to  
> set my
> own.

Not sure I understand, but I guess we'll see how it looks when you  
commit the code.

Just one question - are you planning to implement a "soft delete"  
feature in Cayenne (with appropriate flags per entity settable in the  
Modeler), or just an extension point to hook up your own strategy (or  
both)?

Andrus


Re: Non-physical delete... again

Posted by Andrey Razumovsky <ra...@gmail.com>.
Hi,

> Back then, we
> could set up a delegate to intercept all queries, and I automatically
> added the restricting qualifier to each select query.

I'm afraid, simple qualifier would not be enough, I need to set them for all
joined tables in query (I have simple qualifirer already, by using ObjEntity
qualifier).

2009/6/1 Andrus Adamchik <an...@objectstyle.org>
>
>
> On Jun 1, 2009, at 6:09 PM, Andrey Razumovsky wrote:
>
>>
>>
>> 2.  Deletion strategy for DataDomain. This means I do not always fire
>> DeleteAction, but maybe something else (update action in my case).
>>
>
> Yeah, good idea to move this down the stack. I would love to have the
> ObjectContext level code to stay unchanged, but then generate UPDATE instead
> of DELETE at the lower levels if entity is tagged as "soft delete".


I actually want to see this more generic, i.e. DeletionStrategy interface
with one default implementation (which fires DELETE) and ability to set my
own.


>
>
>  1. DBEntity qualifier. This is same as ObjEntity qualifier, but applied
>> every time DBentity is being added to select sql. I will add DBEntity
>> qualifier 'deleted=false' and drop current ObjEntity's
>>
>
> So does that mean dropping ObjEntity qualifiers completely? (This may or
> may not be a good idea, I am not yet sure myself).


I mean removing them in my Cayenne project of course, not in API.


> Also I think there's a possibility here to address another annoyance in one
> shot - the need to manually set the inheritance discriminator column for new
> objects when inheritance is used. If we can add functionality to expressions
> to not only "get" the value from an object, but also "set" the value, we can
> do both soft delete and auto inheritance update based on an (almost)
> arbitrary exception. Kind of like OGNL framework does...
>
>
Well, I agree this is must-have in Cayenne. But my proposed solution is a
separate feature, because I need intercepting at DbEntity level.

If noone minds against these features, I think I'll look at implementing
'DeleteStrategy' and 'DbEntity qualifiers'

Andrey

Re: Non-physical delete... again

Posted by Andrus Adamchik <an...@objectstyle.org>.
On Jun 1, 2009, at 6:09 PM, Andrey Razumovsky wrote:
>
>
> 2.  Deletion strategy for DataDomain. This means I do not always fire
> DeleteAction, but maybe something else (update action in my case).

Yeah, good idea to move this down the stack. I would love to have the  
ObjectContext level code to stay unchanged, but then generate UPDATE  
instead of DELETE at the lower levels if entity is tagged as "soft  
delete".

> 1. DBEntity qualifier. This is same as ObjEntity qualifier, but  
> applied
> every time DBentity is being added to select sql. I will add DBEntity
> qualifier 'deleted=false' and drop current ObjEntity's

So does that mean dropping ObjEntity qualifiers completely? (This may  
or may not be a good idea, I am not yet sure myself).

Also I think there's a possibility here to address another annoyance  
in one shot - the need to manually set the inheritance discriminator  
column for new objects when inheritance is used. If we can add  
functionality to expressions to not only "get" the value from an  
object, but also "set" the value, we can do both soft delete and auto  
inheritance update based on an (almost) arbitrary exception. Kind of  
like OGNL framework does...

Andrus



Re: Non-physical delete... again

Posted by Mike Kienenberger <mk...@gmail.com>.
I have a legacy Cayenne 1.1.4 app that does the same thing.
I handled it back then by doing something similar.   Back then, we
could set up a delegate to intercept all queries, and I automatically
added the restricting qualifier to each select query.

I never deleted from the application level code .  Instead, I had a
special invalidation manager class that I called instead which would
update the boolean field (and a timestamp) and invalidate all objects
referencing that object.

It worked out well enough, although there were issues with the
invalidation propagating to all sessions exactly when I wanted it to
happen.

However, I didn't have any flattened relationships back then -- too
ignorant to know any better.


On Mon, Jun 1, 2009 at 11:09 AM, Andrey Razumovsky
<ra...@gmail.com> wrote:
> Hi,
>
> We've discussed this time ago, but I'm back now with some ideas.
>
> Current situation:
> I have to use special boolean column named "deleted" in all DB tables. That
> is, I never (or very rarely) do something like "DELETE FROM ..." or
> "context.deleteObject()", instead I do "UPDATE... SET deleted=true" or
> cdo.setDeleted(true). To select only undeleted records, I add qualifier like
> "deleted=true" to every ObjEntity. Also I add pre-update listeners to all
> entities which unregisters object and processes delete rules (also
> respective to 'deleted' field) if 'deleted' flag is set.
> It is obvious that Cayenne cannot completely handle this situation. One
> example is CAY-1109, but it can be workarounded as described above. More
> serious problems are:
> - I cannot use properly flattened relationships, because 'deleted' qualifier
> is not applied to DBEntities selection (e.g. in 'medium' table of
> many-to-many relationship)
> - flattened expressions, e.g. toArtist.name="Rublev" also miss that
> qualifier
> - there is no objects with DELETED state, only with MODIFIED
> ...and so on.
>
> I faced this situation since the first days I used Cayenne. Now when I
> thought about this a bit, I think I can handle it with two new features. I'm
> not sure they completely match Cayenne paradigm, but...
>
> 1. DBEntity qualifier. This is same as ObjEntity qualifier, but applied
> every time DBentity is being added to select sql. I will add DBEntity
> qualifier 'deleted=false' and drop current ObjEntity's
>
> 2.  Deletion strategy for DataDomain. This means I do not always fire
> DeleteAction, but maybe something else (update action in my case).
>
> Any comments much appreciated.
>
> Thanks,
> Andrey
>