I've read the thread How to set DynamoDB range key, String or Map. However after some thought, I came up with more consideration.
I use jackson for serialize & deserialize object in spring app. This app was created by someone else and it's in my hand now to enhance it after its initial release.
There are 2 options to generate the partition key :
Use delimiter ( e.g. value1#value2 )
serialize to JSON ( e.g. {"field1":"value1","field2":"value2"} )
Delimiter-approach:
If I use delimiter, I can create a delimiter that very unlikely (in my case) shows up as part of value1 or value2. This approach will generate shorter string than using jackson. Also the official DynamoDB documentation give example with this approach.
However this approach means I need to document the order and rule. In case other app (e.g. Node-based or Go use the same DB, I need to tell them to read the docs.
Jackson-approach:
If I use jackson, it's quite self documented, I can use #JsonFormat to maintain formatting consistency, I can use #JsonFilter to pick which fields I want to serialize for this case. I can use #JsonProperty to shorten field name (although I doubt that I'll need to shorten field name), and also the implementation will be more robust.
But then again, in my case there's already a table that already implemented the delimiter approach. It means that there will be two different formatting needs to be written on the app documentation. Also I think that a key generation should be very explicit.
I'm a bit pros to delimiter-approach for the sake of consistent formatting, but then again I might miss or haven't see the good things from Jackson-approach, especially in the future of this project development.
My question is : should I use the delimiter-approach or the other?
I have a situation where i am changing few parameters values of an Object.
UserDetails has around 14 parameters.I am changing the values of few parameters and submitting them from a Form .These values should get updated on the database back-end.
Are there any inbuilt functions to check if any of the values got changed?
Are there any inbuilt functions to say which of the values got changed?
No.
Are there any inbuilt functions to check if any of the values got changed?
No.
However, you can implement your own methods to test these things. An equals method is easy to implement, and indeed many IDEs have "wizards" to generate them. A "what has changed" method is more complicated. The complexity comes in how the method tells the caller what fields have changed, and how the caller can make use of this information.
Alternatively, Apache Commons provides a class called EqualsBuilder that uses reflection, etcetera to compare objects based on their fields.
I also agree with JB Nizet. If you are doing this in an attempt to optimize database updates, you are probably wasting your time. You are probably better off just saving the all of the fields.
Consider this. Unless your front-end caches the old values of the fields read from the database while the user is updating the form (or not), your front end is going to have to re-query the database to find the old value. You would be better off just issuing the UPDATE to update all of the fields than doing a SELECT followed by a conditional UPDATE is something has changed.
Probably you can check this link.. I am not sure this can be done in java. But, you can try with javascript. Please check this link. You can do with EXT.js
handler: function(btn, evt) {
var f = btn.up('form').getForm();
f.submit({
url: '/some-path-on-my-server/save/,
getParams: function(useModelValues) {
var falseVal = false;
var fieldParams = this.form.getValues(falseVal, true, this.submitEmptyText !== falseVal, useModelValues, true);
return Ext.apply({}, fieldParams);
}
});
}
https://www.sencha.com/forum/showthread.php?173867-I-want-to-submit-only-dirty-field-values.
We are building a micro-service REST api in groovy as part of a more complex application. This service would only just be a simple CRUD operations.
We are using groovy and on a GET we need to pull a record from the database ( mongodb ), and return the object after changing the format of some fields ( for backward compatibility ), something on these lines:
def object = collection.findOne(query)
object.field3 = object.field2.collect { [..]}
return object
I am not very experienced in groovy or java ( I worked more extensively on ruby/python/clojure ), but I would normally have a domain object:
class Foo {
String _id
String field1
Array field2
Map toMap() {
[field1: field1, field3: field2.collect {}, field2: field2]
}
}
and then just go
foo = new Foo(objectMapFromDb)
foo.toMap()
and some of the benefits that I see by using this approach is that I can look at the domain object and have an idea of what the structure of the object in the database is, I can get some type safety if I want to but more importantly ( and that's what drove my decision ) is that the code for converting the map is encapsulated in a function and can be easily re used in other part of the project
A more senior developer questioned this approach mentioning YAGNI and stating that domain objects are too complex, and reverted back to just changing changing the map as above.
I am a bit puzzled, I tried to look around for information about avoiding domain objects but I can't find anything similar to that ( I have looked at the anaemic domain model, but this seems to take it to the extreme ). About yagni I don't feel it applies in this case.
I personally don't see anything terribly wrong with that, for a simple application seems like a fine solution, but the novelty of this approach really stimulate my curiosity.
Any thought on this? Am I missing something?
Thanks
I want to use Hazelcast in my Java application, but I also have .net applications which need to get/set data to/from the Hazelcast cache. I thought to use the "rest" approach. I have 2 questions:
1) How can I post and get a complex type? If I have a Person object with fields name (String), age (Integer), birthDate (Date), and sex (Enum), how should I post this info and how should I parse person info?
2) I have a cached IMap<String, String>. After I post data "three" with key "3" from a Poster plugin, on the Java side map.get("3") returns something like:
RestValue{contentType='text/plain;charset=utf-8', value="three"}"
I expect this code to return just "three" without any cast operation.
I will be pleased if you give information about this issues.
Thanks in advance...
It sounds like you have a couple of different types of issues here with your current setup.
1) I don't have a good answer for this because I don't actually know much about rest clients in .net. You also may also get better results if you change your architecture as mentioned below.
2) It looks like the problem you have here is that you're just storing the raw request object(RestValue) in the IMap rather than storing the content of that object. Usually requests to a rest api contain more information than just the value sent to your server so you'll have to extract the value from the RestValue in your rest api. Hazelcast RestValue has a method called getValue(), so you should just be able to call getValue() which returns a byte[]. You should then just convert that byte[] to a String (or whatever datatype you prefer to store, maybe int in this case) and store the result in your IMap instead of just storing the entire RestValue object.
As far as having .net + java architecture, it may be best to run a Hazelcast-server node in whichever language you prefer and then have a .net hazelcast-client node and a java hazelcast-client node that are all connected to the same cluster. This way you can have all of your .net code run on your .net client completely separattd from your java infrastructure and communicate between the separate languages using hazelcast.
I am trying to query the google datastore for something like (with pm --> persistanceManager):
String filters = "( field == 'value' || field == 'anotherValue' )";
Query query = pm.newQuery(myType.class, filters);
When I execute - I am getting back: App Engine datastore does not support operator OR.
What's the best approach in people experience for this kind of queries?
Any help appreciated!
Perform multiple queries. The Datastore, like all other databases, isn't able to efficiently execute disjunctions. Unlike other databases, it exposes this difficulty to the user, to make it clear that what you're doing isn't efficient. Your only solution is to execute multiple queries - one for each or - and combine them.
I don't know if GAE's JDO and JPA implementations support this, but using the low-level API, you can use the operator IN for this, in one query.
Query query = new Query("Issue");
List<String> list = Arrays.asList("NEW", "OPEN", "ACCEPTED");
query.addFilter("status", FilterOperator.IN, list);
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
PreparedQuery preparedQuery = datastore.prepare(query);
for (Entity entity : preparedQuery.asIterable()) {
// should iterate over 'NEW', 'OPEN' and 'ACCEPTED' issues
}
According to Google App Engine - Queries and Indexes:
Query Filters
A filter specifies a field name,
an operator, and a value. The value
must be provided by the app; it cannot
refer to another property, or be
calculated in terms of other
properties. The operator can be any of
the following: < <= == >= >
Note: The Java datastore interface does not support the != and
IN filter
operators that are implemented in the
Python datastore interface. (In the
Python interface, these operators are
implemented in the client-side
libraries as multiple datastore
queries; they are not features of the
datastore itself.)
The subject of a filter can be any
object field, including the primary
key and the entity group parent (see
Transactions).
An entity must match all filters to be
a result. In the JDOQL string syntax,
multiple filters are specified
separated by && (logical "and").
Other logical combinations of filters
(logical "or", "not") are not
supported.
Due to the way the App Engine
datastore executes queries, a single
query cannot use inequality filters
(< <= >= >) on more than one
property. Multiple inequality filters
on the same property (such as querying
for a range of values) are permitted.
See Restrictions on Queries.
Basically you're either going to have to restructure your data so that you can find what you're looking for with one condition or multiple "and" conditions or you're going to have to retrieve the data via two (or more) queries and filter/combine it in your code.
Sorry I'm late to the game.. I just ran across your question today.
Another way to "simulate" 'IN' and 'OR' behavior is to use the "low level" Datastore API. The DatastoreService supports a get() method that accepts a collection of Keys and returns a Map of all Entities that matched the passed in Keys. It's an interface, but there's a handy DatastoreServiceFactory available that will dispense a ready-to-use instance.
Unfortunately, Google decided that they don't want to promote this low-level API approach and prefer that developers use JDO or JPA, so there's no documentation available other than the JavaDocs and whatever code samples that you might find when you Google "DatastoreService".
TL
Late breaking News.. at least I'm just getting it. As I was downloading the latest Java SDK for GAE I noticed on the Release Notes that "Issue 29: Expose batch gets" was fixed in the latest release (v1.2.1). Basically it seems that we (I'm looking for the same support it seems) may have a JDO based alternative rather than having to drop down to the "low-level" Datastore API. I've just downloaded the latest Java GAE SDK so I haven't had an opportunity to test anything yet, but I wanted to give you a heads-up ASAP. I'll post anything more I learn after I've had a chance to confirm this "fix".
Please accept my apologies if I've broken StackOverflow etiquette by re-posting my comment as an answer, but I decided to do it for two reasons. Firstly because, even though it's me addressing the same issue again, IMHO this new information appears to provide a completely different "answer" to the problem. And secondly, I was concerned that the comment form might not get your attention before you'd spent a great deal of time looking into the first answer that I provided.
Next time I'll think more carefully before acting.
TL
One way to simplify having to "do it yourself" might be to use parameterized queries:
Query query = pm.newQuery(mytype.class);
query.setFilter("field == autoParam");
query.declareParameters("String autoParam");
List<String> params = myListOfThingsFieldCanBeEqualTo;
Set merged = new HashSet();
for (String f : params) {
merged.addAll(q.execute(f));
}
Contrary to cletus' answer, OR-ing works, in more recent version of App Engine anyway.
Indeed, I found OR-ing not working in App Engine 1.3.0 that I had, but according to Google App Engine - Queries and Indexes (the same source cletus referred to in his answer),
An entity must match all filters to be a result. In the JDOQL string syntax, you can separate multiple filters with || (logical "or") and && (logical "and"), although keep in mind that || can only be employed when the filters it separates all have the same field name. In other words, || is only legal in situations where the filters it separates can be combined into a single contains() filters.
I figured since his answer (and since I last updated my App Engine), App Engine must have been upgraded on this matter.
Update App Engine to 1.3.4, and the OR-ing works! Though with the limitation.
Thanks to cletus anyway:)
You can use the contains method
String filters = "( :values.contains(field) )";
Query query = pm.newQuery(myType.class, filters);