Read-only contexts?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Read-only contexts?

Alexander Frei
Hi,

I searched for a while, but wasn’t able to find a solution to make an ObjectContext “read-only”.
Maybe I'm missing something.

The point is:
As suggested many times, there are situations where it makes sense to have a shared read-only ObjectContext and other ObjectContexts to commit changes.
I can certainly handle two and more ObjectContexts, but I need to lock out other users / applications which can somehow gain access to persistent objects instantiated through the assumed read-only shared context, since any application that has access to such objects (maybe obtained from a service class that is expected to return read-only objects) could simply call object.getObjectContext().commitChanges(). By the way, this would also commit unwanted temporary changes that happen elsewhere in the main application or in the service class.

Is there a method like CONTEXT.makeReadOnly() to make sure that any objects that resides in this specific ObjectContext cannot be changed?
Even better, is there a way to let persistent objects, that are bound to a read-only context, throw an exception?

Should this be possible, there is only one question left: would it still be possible to transfer objects retrieved through a read-only ObjectContext  to a read-write ObjectContext, by calling localObject(readWriteContext)?

Any help would be greatly appreciated.
Alexander

Reply | Threaded
Open this post in threaded view
|

Re: Read-only contexts?

Michael Gentry
Hi Alexander,

I don't believe what you are asking for is currently doable, even in the
latest 4.0 milestone release.

An ObjectContext doesn't know anything about read-only.  You can make a
Cayenne object read-only in Cayenne Modeler, however this just omits
setter-type methods.  CayenneDataObject, which all Cayenne database objects
inherit from, doesn't actually restrict setting values if you flag it as
read-only in the modeler.  You can directly call writeProperty(),
writePropertyDirectly(), removeToManyTarget(), etc on the objects.

I think this feature would be fairly easy to add (the information is
already in the model's XML files [1]), so perhaps it could be added before
4.0 final.

I'd suggest:

1. Add a read-only flag to DataContext and friends.  If you call
commitChanges() on a read-only context, throw an exception.
2. Alter each CayenneDataObject which modifies data (writeProperty(), etc)
to check the entity's read-only status AND the context's read-only status.
If either is read-only and you are trying to sneak a change in, throw an
exception.

Does this sound like the right approach (to you and other Cayenne users)?

As to your localObject() question, I think it should adhere to the 1/2
semantics I just mentioned.
Thanks,

mrg

[1] <obj-entity name="..." className="..." readOnly="true"
dbEntityName="..." superClassName="...">



On Fri, May 5, 2017 at 6:29 AM, Alexander <[hidden email]> wrote:

> Hi,
>
> I searched for a while, but wasn’t able to find a solution to make an
> ObjectContext “read-only”.
> Maybe I'm missing something.
>
> The point is:
> As suggested many times, there are situations where it makes sense to have
> a shared read-only ObjectContext and other ObjectContexts to commit changes.
> I can certainly handle two and more ObjectContexts, but I need to lock out
> other users / applications which can somehow gain access to persistent
> objects instantiated through the assumed read-only shared context, since
> any application that has access to such objects (maybe obtained from a
> service class that is expected to return read-only objects) could simply
> call object.getObjectContext().commitChanges(). By the way, this would
> also commit unwanted temporary changes that happen elsewhere in the main
> application or in the service class.
>
> Is there a method like CONTEXT.makeReadOnly() to make sure that any
> objects that resides in this specific ObjectContext cannot be changed?
> Even better, is there a way to let persistent objects, that are bound to a
> read-only context, throw an exception?
>
> Should this be possible, there is only one question left: would it still
> be possible to transfer objects retrieved through a read-only
> ObjectContext  to a read-write ObjectContext, by calling
> localObject(readWriteContext)?
>
> Any help would be greatly appreciated.
> Alexander
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Read-only contexts?

Musall, Maik
In reply to this post by Alexander Frei
Hi Alexander,

I suppose you could create your own ObjectContext subclass which does it, by overriding commitChanges() and related methods. I always recommend using custom subclasses of ObjectContext in any case, with a factory providing them, so you could always change the behaviour by extending the factory to produce other subclasses.

Maik


> Am 05.05.2017 um 12:29 schrieb Alexander <[hidden email]>:
>
> Hi,
>
> I searched for a while, but wasn’t able to find a solution to make an ObjectContext “read-only”.
> Maybe I'm missing something.
>
> The point is:
> As suggested many times, there are situations where it makes sense to have a shared read-only ObjectContext and other ObjectContexts to commit changes.
> I can certainly handle two and more ObjectContexts, but I need to lock out other users / applications which can somehow gain access to persistent objects instantiated through the assumed read-only shared context, since any application that has access to such objects (maybe obtained from a service class that is expected to return read-only objects) could simply call object.getObjectContext().commitChanges(). By the way, this would also commit unwanted temporary changes that happen elsewhere in the main application or in the service class.
>
> Is there a method like CONTEXT.makeReadOnly() to make sure that any objects that resides in this specific ObjectContext cannot be changed?
> Even better, is there a way to let persistent objects, that are bound to a read-only context, throw an exception?
>
> Should this be possible, there is only one question left: would it still be possible to transfer objects retrieved through a read-only ObjectContext  to a read-write ObjectContext, by calling localObject(readWriteContext)?
>
> Any help would be greatly appreciated.
> Alexander
>

Reply | Threaded
Open this post in threaded view
|

Re: Read-only contexts?

Michael Gentry
In reply to this post by Michael Gentry
#2 should've read:

2. Alter CayenneDataObject to check the entity's read-only status AND the
context's read-only status.  (Change writeProperty(), etc.)  If either is
read-only and you are trying to sneak a change in, throw an exception.

mrg


On Fri, May 5, 2017 at 7:04 AM, Michael Gentry <[hidden email]> wrote:

> Hi Alexander,
>
> I don't believe what you are asking for is currently doable, even in the
> latest 4.0 milestone release.
>
> An ObjectContext doesn't know anything about read-only.  You can make a
> Cayenne object read-only in Cayenne Modeler, however this just omits
> setter-type methods.  CayenneDataObject, which all Cayenne database objects
> inherit from, doesn't actually restrict setting values if you flag it as
> read-only in the modeler.  You can directly call writeProperty(),
> writePropertyDirectly(), removeToManyTarget(), etc on the objects.
>
> I think this feature would be fairly easy to add (the information is
> already in the model's XML files [1]), so perhaps it could be added before
> 4.0 final.
>
> I'd suggest:
>
> 1. Add a read-only flag to DataContext and friends.  If you call
> commitChanges() on a read-only context, throw an exception.
> 2. Alter each CayenneDataObject which modifies data (writeProperty(), etc)
> to check the entity's read-only status AND the context's read-only status.
> If either is read-only and you are trying to sneak a change in, throw an
> exception.
>
> Does this sound like the right approach (to you and other Cayenne users)?
>
> As to your localObject() question, I think it should adhere to the 1/2
> semantics I just mentioned.
> Thanks,
>
> mrg
>
> [1] <obj-entity name="..." className="..." readOnly="true"
> dbEntityName="..." superClassName="...">
>
>
>
> On Fri, May 5, 2017 at 6:29 AM, Alexander <[hidden email]> wrote:
>
>> Hi,
>>
>> I searched for a while, but wasn’t able to find a solution to make an
>> ObjectContext “read-only”.
>> Maybe I'm missing something.
>>
>> The point is:
>> As suggested many times, there are situations where it makes sense to
>> have a shared read-only ObjectContext and other ObjectContexts to commit
>> changes.
>> I can certainly handle two and more ObjectContexts, but I need to lock
>> out other users / applications which can somehow gain access to persistent
>> objects instantiated through the assumed read-only shared context, since
>> any application that has access to such objects (maybe obtained from a
>> service class that is expected to return read-only objects) could simply
>> call object.getObjectContext().commitChanges(). By the way, this would
>> also commit unwanted temporary changes that happen elsewhere in the main
>> application or in the service class.
>>
>> Is there a method like CONTEXT.makeReadOnly() to make sure that any
>> objects that resides in this specific ObjectContext cannot be changed?
>> Even better, is there a way to let persistent objects, that are bound to
>> a read-only context, throw an exception?
>>
>> Should this be possible, there is only one question left: would it still
>> be possible to transfer objects retrieved through a read-only
>> ObjectContext  to a read-write ObjectContext, by calling
>> localObject(readWriteContext)?
>>
>> Any help would be greatly appreciated.
>> Alexander
>>
>>
>
Reply | Threaded
Open this post in threaded view
|

Re: Read-only contexts?

Alexander Frei
Hi,

thank you and Maik for answering so fast. You saved me a lot of time searching around for nothing.

Your suggestion seems to be the right approach.
I’d consider making the read-only flag in the ObjectContext final, as to prevent unintended changes. Therefore it has to be set in the ObjectContext’s constructor.

A fail fast behavior should be considered for nested ObjectContexts, i.e. commitChangesToParent() should check the parent’s read-only flag, unless the nested context’s read-only flag is copied from the parent on instantiation (in this case ObjectContextFactory class has to be changed too)..

Let’s hope this feature will be added before 4.0 final.

For now subclassing is a good option.

Thanks again
Alexander


On 2017-05-05 13:08 (+0200), Michael Gentry <[hidden email]> wrote:

> #2 should've read:
>
> 2. Alter CayenneDataObject to check the entity's read-only status AND the
> context's read-only status.  (Change writeProperty(), etc.)  If either is
> read-only and you are trying to sneak a change in, throw an exception.
>
> mrg
>
>
> On Fri, May 5, 2017 at 7:04 AM, Michael Gentry <[hidden email]> wrote:
>
> > Hi Alexander,
> >
> > I don't believe what you are asking for is currently doable, even in the
> > latest 4.0 milestone release.
> >
> > An ObjectContext doesn't know anything about read-only.  You can make a
> > Cayenne object read-only in Cayenne Modeler, however this just omits
> > setter-type methods.  CayenneDataObject, which all Cayenne database objects
> > inherit from, doesn't actually restrict setting values if you flag it as
> > read-only in the modeler.  You can directly call writeProperty(),
> > writePropertyDirectly(), removeToManyTarget(), etc on the objects.
> >
> > I think this feature would be fairly easy to add (the information is
> > already in the model's XML files [1]), so perhaps it could be added before
> > 4.0 final.
> >
> > I'd suggest:
> >
> > 1. Add a read-only flag to DataContext and friends.  If you call
> > commitChanges() on a read-only context, throw an exception.
> > 2. Alter each CayenneDataObject which modifies data (writeProperty(), etc)
> > to check the entity's read-only status AND the context's read-only status.
> > If either is read-only and you are trying to sneak a change in, throw an
> > exception.
> >
> > Does this sound like the right approach (to you and other Cayenne users)?
> >
> > As to your localObject() question, I think it should adhere to the 1/2
> > semantics I just mentioned.
> > Thanks,
> >
> > mrg
> >
> > [1] <obj-entity name="..." className="..." readOnly="true"
> > dbEntityName="..." superClassName="...">
> >
> >
> >
> > On Fri, May 5, 2017 at 6:29 AM, Alexander <[hidden email]> wrote:
> >
> >> Hi,
> >>
> >> I searched for a while, but wasn’t able to find a solution to make an
> >> ObjectContext “read-only”.
> >> Maybe I'm missing something.
> >>
> >> The point is:
> >> As suggested many times, there are situations where it makes sense to
> >> have a shared read-only ObjectContext and other ObjectContexts to commit
> >> changes.
> >> I can certainly handle two and more ObjectContexts, but I need to lock
> >> out other users / applications which can somehow gain access to persistent
> >> objects instantiated through the assumed read-only shared context, since
> >> any application that has access to such objects (maybe obtained from a
> >> service class that is expected to return read-only objects) could simply
> >> call object.getObjectContext().commitChanges(). By the way, this would
> >> also commit unwanted temporary changes that happen elsewhere in the main
> >> application or in the service class.
> >>
> >> Is there a method like CONTEXT.makeReadOnly() to make sure that any
> >> objects that resides in this specific ObjectContext cannot be changed?
> >> Even better, is there a way to let persistent objects, that are bound to
> >> a read-only context, throw an exception?
> >>
> >> Should this be possible, there is only one question left: would it still
> >> be possible to transfer objects retrieved through a read-only
> >> ObjectContext  to a read-write ObjectContext, by calling
> >> localObject(readWriteContext)?
> >>
> >> Any help would be greatly appreciated.
> >> Alexander
> >>
> >>
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Read-only contexts?

Michael Gentry
Hi Alexander,

Those are also good suggestions for implementing this feature.

Thanks,

mrg


On Fri, May 5, 2017 at 9:19 AM, Alexander <[hidden email]> wrote:

> Hi,
>
> thank you and Maik for answering so fast. You saved me a lot of time
> searching around for nothing.
>
> Your suggestion seems to be the right approach.
> I’d consider making the read-only flag in the ObjectContext final, as to
> prevent unintended changes. Therefore it has to be set in the
> ObjectContext’s constructor.
>
> A fail fast behavior should be considered for nested ObjectContexts, i.e.
> commitChangesToParent() should check the parent’s read-only flag, unless
> the nested context’s read-only flag is copied from the parent on
> instantiation (in this case ObjectContextFactory class has to be changed
> too)..
>
> Let’s hope this feature will be added before 4.0 final.
>
> For now subclassing is a good option.
>
> Thanks again
> Alexander
>
>
> On 2017-05-05 13:08 (+0200), Michael Gentry <[hidden email]> wrote:
> > #2 should've read:
> >
> > 2. Alter CayenneDataObject to check the entity's read-only status AND the
> > context's read-only status.  (Change writeProperty(), etc.)  If either is
> > read-only and you are trying to sneak a change in, throw an exception.
> >
> > mrg
> >
> >
> > On Fri, May 5, 2017 at 7:04 AM, Michael Gentry <[hidden email]>
> wrote:
> >
> > > Hi Alexander,
> > >
> > > I don't believe what you are asking for is currently doable, even in
> the
> > > latest 4.0 milestone release.
> > >
> > > An ObjectContext doesn't know anything about read-only.  You can make a
> > > Cayenne object read-only in Cayenne Modeler, however this just omits
> > > setter-type methods.  CayenneDataObject, which all Cayenne database
> objects
> > > inherit from, doesn't actually restrict setting values if you flag it
> as
> > > read-only in the modeler.  You can directly call writeProperty(),
> > > writePropertyDirectly(), removeToManyTarget(), etc on the objects.
> > >
> > > I think this feature would be fairly easy to add (the information is
> > > already in the model's XML files [1]), so perhaps it could be added
> before
> > > 4.0 final.
> > >
> > > I'd suggest:
> > >
> > > 1. Add a read-only flag to DataContext and friends.  If you call
> > > commitChanges() on a read-only context, throw an exception.
> > > 2. Alter each CayenneDataObject which modifies data (writeProperty(),
> etc)
> > > to check the entity's read-only status AND the context's read-only
> status.
> > > If either is read-only and you are trying to sneak a change in, throw
> an
> > > exception.
> > >
> > > Does this sound like the right approach (to you and other Cayenne
> users)?
> > >
> > > As to your localObject() question, I think it should adhere to the 1/2
> > > semantics I just mentioned.
> > > Thanks,
> > >
> > > mrg
> > >
> > > [1] <obj-entity name="..." className="..." readOnly="true"
> > > dbEntityName="..." superClassName="...">
> > >
> > >
> > >
> > > On Fri, May 5, 2017 at 6:29 AM, Alexander <[hidden email]> wrote:
> > >
> > >> Hi,
> > >>
> > >> I searched for a while, but wasn’t able to find a solution to make an
> > >> ObjectContext “read-only”.
> > >> Maybe I'm missing something.
> > >>
> > >> The point is:
> > >> As suggested many times, there are situations where it makes sense to
> > >> have a shared read-only ObjectContext and other ObjectContexts to
> commit
> > >> changes.
> > >> I can certainly handle two and more ObjectContexts, but I need to lock
> > >> out other users / applications which can somehow gain access to
> persistent
> > >> objects instantiated through the assumed read-only shared context,
> since
> > >> any application that has access to such objects (maybe obtained from a
> > >> service class that is expected to return read-only objects) could
> simply
> > >> call object.getObjectContext().commitChanges(). By the way, this
> would
> > >> also commit unwanted temporary changes that happen elsewhere in the
> main
> > >> application or in the service class.
> > >>
> > >> Is there a method like CONTEXT.makeReadOnly() to make sure that any
> > >> objects that resides in this specific ObjectContext cannot be changed?
> > >> Even better, is there a way to let persistent objects, that are bound
> to
> > >> a read-only context, throw an exception?
> > >>
> > >> Should this be possible, there is only one question left: would it
> still
> > >> be possible to transfer objects retrieved through a read-only
> > >> ObjectContext  to a read-write ObjectContext, by calling
> > >> localObject(readWriteContext)?
> > >>
> > >> Any help would be greatly appreciated.
> > >> Alexander
> > >>
> > >>
> > >
> >
>