I have some JSON data that I've deserialized to a hierarchical structure or Map<String, Object>. I want to access some of this data via SpEL as read-only, and some of it as writeable, based on certain parent properties. For example, let's say that all child properties of "readOnlyGroup" should be read-only, and "writeableGroup" should be writeable. So, "readOnlyGroup.prop1.prop2.prop3" should be read-only, and "writeableGroup.prop1.prop2.prop3" should be writeable. I see that PropertyAccessor supports canRead() and canWrite(), but I'm not seeing how I can use this to enforce these constraints on child properties, without having PropertyAccessors for every child object -- which would be difficult anyway since they're just Maps. Thoughts? Thanks!
Related
I want to do Spring expression evaluation against a root object that is a hierarchy of Maps, Lists, and primitive objects. Is there any way to selectively make parts of the hierarchy read-only and other parts writeable with SpEL? Thanks!
From my understanding the attributes of a Backbone.js model are supposed to be declared as somewhat private member variables by saying
this.set({ attributeName: attributeValue })
// accessing the value
this.get('attributeName');
But when I am writing functions whitin the actual model it seems much simpler to say like this:
this.attributeName = attributeValue;
// accessing the value
this.attributeName;
Also I would assume that the latter version would be faster to process since it doesn't go through backbone.js's event management.
So I was wondering how you pros do with attributes that are primarily used internally in the model. These are the attributes that one would actually want to be a bit shielded from the outside so having them exposed like in the latter example maybe isn't right still. When I have been looking at examples for the backbone.js view which doesn't have get and set methods it seems fine to do like in the second example. So is there any nice rule of thumb when to use get/set(attribute) or this.attribute when coding within the model? Or maybe an example of a model that makes this clearer?
When to use model.get(property) and model.set(...)
You should use get and set to access the model's data. This means any attributes that are part of the model's serialized representation that is retrieved using fetch and persisted using save.
When to use model.attributes.property
Never.
You should always use get, and especially set, instead of accessing the model.attributes object directly, although I've seen conflicting opinions about this. I believe there is a contract between a model and it's consumers, which guarantees that the consumer can be notified of any changes to the model's data using the change event. If you modify the internal attributes object directly, events are not sent and this contract is broken. Backbone events are very fast, especially if you don't have any listeners attached to them, and it's not a point that benefits from over-optimization on your part.
Although accessing the attributes directly instead of get is quite harmless on it's own, it should be avoided so the attributes object can be considered totally, completely private.
If you absolutely need to prevent some change triggering events, you can use the silent:true option: model.set({key:val}, {silent:true}). This does break the aforementioned contract, and even Backbone's own documentation gives the following caveat:
Note that this is rarely, perhaps even never, a good idea. Passing through a specific flag in the options for your event callback to look at, and choose to ignore, will usually work out better.
When to use model.property
Any properties which are not data, i.e. temporary state variables, calculated properties etc. can be attached directly to the model entity. These properties should be considered temporary and transitive: they can be recreated upon model initialization or during its lifetime, but they should not be persisted, whether public or private. A typical naming convention is to prefix private properties with the _ character as follows:
this._privateProperty = 'foo';
this.publicProperty = 'bar';
Never is an incomplete answer.
Sometimes you want access to the collection of model attributes - whatever those attributes might be. Consider a utility method to perform calcs on attributes, format them for output, etc.
A convenient way to do this is to access model.attributes
Consider one alternative, below:
var attributesNames = ['foo', 'bar', 'baz'];
var attributes = _(attributesNames ).map(function(attr) { return model.get(attr); });
callSomeUtilityMethod(attributes);
Two problems:
We've introduced coupling in the "attributeNames" collection. What if that list changes?
We've lost the association of name/value. We could rewrite the map above, but it becomes more work.
In this scenario, it's much more convenient to do something like this:
callSomeUtilityMethod(model.attributes);
I know you can set client permissions for a whole dataset like so:
<dataset name="foo" databroker="bar" client-permissions="view"/>
Is there a way to set client-permissions on just one field (similar to how other metadata like "valid" can be set for one field)?
Note: this is in Aviarc 3.5.0, so data bindings are not available.
Update: The use case I have in mind is a search parameters dataset. If I arrive at the search screen from a certain location then one parameter should be locked, because the search results should be filtered by that parameter.
Creating a new databroker for what amounts to a scratch search parameters dataset, just so I can set the read-only property on a single field, is really looking like overkill.
Update: Just to clarify, the dataset doesn't currently have any databroker bound to it, it is just used like a hash to store search parameters.
There isn't currently a way to set client-permissions on a single column/field.
It should be possible to set a datarule on a column which prevents the column being writable by anything other than dataset refreshes.
When I have individual pieces of data which should be read-only but are included in client-writable datasets, I keep copies of the data in non-client writable datasets and overwrite the client-writable ones when they get back.
As mentioned, data rules have the facility to set read-only on individual fields. They can be set on a given field for all rows, or on a field of a single row.
Adam has mentioned that creating a separate databroker for this case would be overkill, which is correct. The DataBinding layer is intended to provide this kind of specialization for certain use cases within your application.
So, you would create a DataBinding, pointing at your search DataBroker, that adds the rule you require to either an existing operation, or a new one that you define. The Dataset is then bound to the DataBinding instead of the DataBroker and from then on is used in the normal way.
The intention is that rules bound by DataBrokers apply to all data of the type supplied through that broker, so would be rules focusing on data integrity, formatting etc.
The DataBindings on the other hand are a layer within the application allowing you to bind rules relating to user interaction with the data, as in your example. It is expected that there might be multiple databindings for a given broker, each for a different application path or user task to interact with that data in a different way.
It should be possible to work around this by isolating the parameter I want to be read-only into its own dataset, and setting client-permissions to 'view' just for that parameter/dataset.
This does add the overhead of having to add a special case for that parameter, but I shouldn't need to extend it to any more special cases.
I have a very basic query. I am using WPF Binding to edit a object which is loaded by a ISession. If somebody edits this object in the form, because of two way binding and a stateful session, whenever I close the session, changes to the object made in the form are stored back in the database. Which is the best way to avoid this?
The methods I know:
Shadow copy the object and use the copied object as the DataContext (the method I am using as of now).
ISession.Clear
Use IStatelessSession.
Is there any way to reset the object to it's original form before closing the ISession?
If you look here: http://nhforge.org/wikis/howtonh/finding-dirty-properties-in-nhibernate.aspx
It is an example of finding dirty properties. NHibernate internally tracks a persistent object's state by way of the EntityEntry object.
This is useful for you, because with a little modification to the method above, you're able to get old values back ... which you can use to reset the properties.
As for closing your session causing the object to be flushed to the database, you can set the session FlushMode to FlushMode.Never. This will mean no database sync occurs until you call Session.Flush().
Alternatively, you can hook into IFlushEntityEventListener to reset the object state. There are a reasonable examples of using the NHibernate event system on google.
See Managing the caches on NHibernate Forge:
When Flush() is subsequently called, the state of that object will be synchronized with the database. If you do not want this synchronization to occur or if you are processing a huge number of objects and need to manage memory efficiently, the Evict() method may be used to remove the object and its collections from the first-level cache.
I think that sounds like what you want.
I would suggest the use of transactions. You just rollbackthe transaction if that is the case? what do you think?
What is the best practice when it comes to reference properties for parent/ancestor relations in AppEngine? Should I add a reference property pointing from the parent to the child to make it easy to access the child in the parent, or should I just "suck it up" and do a ancestor query from the parent to get it's children.
If there is only one child, you could use a known key_name so you can directly fetch the child (since you know the parent's key). This can be useful because any time you know the parent's key name or id you can easily fetch the child directly.
child_key = db.Key.from_path('ChildKind', 'knownname', parent=parent_key)
child = db.get(child_key)
If there are multiple children you could potentially store a list of keys (it can be unindexed) on the parent, or use an ancestor query. I would say it depends how your data is updated, reported on (presented), and the volume of data. In other words it depends on the needs of your application.