Is there any way to tell Glassfish that the hash value for a certain data member of an entity class should be calculated and stored in the database instead of the original value?
If you modify the getter of a field to produce its hash instead of original value, you might end up with the hash stored instead.
If your database has a hash function, other option is to issue native query using entitiy manager.
Give it a try
Related
I am relatively new to Mongodb and I have an idea in mind but not sure how to go about it.
What I would like to do is essentially hash a mongodb document (preferably it's Json format so it is not database specific) and store that hash somewhere with a reference to that specific document. This needs to allow me to retrieve the document in the future via a query and compare against the stored hash.
My idea is to get the json representation of the DBObject, hash it and then add the hash as a field to that specific document before persisting it. Then when querying for the object, make sure to exclude the hash field from the answer so the returned DBObject includes the same hash.
1 - Does mongodb always return a consistent DBObject format which will always convert to the same json so that the hash would always be the same
2 - Would such an implementation even be viable? As in storing the hash with the object itself, essentially changing the object (thus making the hash invalid) but getting around by not retrieving that field in the response
3 - If the implementation would not work, what would be the simplest way to store the hash, another object with a reference to the original document?
1- Does mongodb always return a consistent DBObject format which will always convert to the same json so that the hash would always be the same. - No Mongo does not guarantee the order so the json can be different based on what kind of updates were done on the document. There is no guarantee that the field order will be consistent, or the same, after an update. If no such order changing updates were done on it then the order should be preserved MongoDB update on Field Order .
But when you serialize the json into an object using Jackson or something else it will serialize to the same object and should have the same hash.
2 - Would such an implementation even be viable? As in storing the hash with the object itself, essentially changing the object (thus making the hash invalid) but getting around by not retrieving that field in the response.
Looks like from this answer you can use Jakson or Gson to hash the json object, even though it is not ordered.
excluding a field should not be a problem.
If you store the hash as a field in the object itself all the write queries that save ( which is an overwrite of the entire document ) will have to write the hash into it. If any of them fail to do so the hash will be lost.
An update query will have another problem since along with changing the data it also has to update the hash of the document. So this will have to involve reading the object, modifying it, computing the hash and storing it back. You will not be able to use the primitive update queries.
If you make the hash as the primary key which is _id field that would mitigate this problem although you probably need it for something else.
3- The simplest way would be to store the _id of the document to be hashed into another collection along with the hash as the _id of the new collection.
{
"_id":<hash code of docuemnt>,
"refer":<_id of the document to be hashed>
}
This would involve multiple read writes which will hurt performance and depending on your use case it
Mongo according to me is a simplistic database designed to store and retrieve objects. If you have the need to do something complicated with it other than retrieving fast and writing its probably not fit for the task.
I'm looking for an efficient way to implement compare-and-swap operation in Berkeley DB. Right now I'm using really old version, however at first glance even the latest one (distributed from Oracle website) does not have a single method for such operation.
I was looking for a some kind of method like
replace(Transaction, Key, ExpectedValue, NewValue)
with the following semantics: DB gets value associated with a given key, if this value exists and it is equal to ExpectedValue then this value will be changed to NewValue, otherwise method returns unsuccessful OperationStatus.
Looks like there is no method like that, so I'm wondering how is this supposed to be done in the most efficient way.
Right now I'm using the following approach: I do
db.get(null, key) -> {currentValue, version}
db.put(null, key, {currentValue, newRandomIdVersion})
db.get(null, key)
I compare value and version, if they match I do final update erasing old version. If any step fail, the whole process restarts.
I feel that this is very suboptimal - am I wrong?
My solution in update to my question is wrong - however only slight modification is required to make it better.
The solution might be as follows: create separate DB for storing locks that will hold associations of key to some counter. This DB should allow sorted duplicates (so that Database.get would return smallest value associated with a given key). Then use shared monotonically increasing counter. Multiple threads attempting to do CAS will get values from this counter and store key-value pairs in that lock DB. Thread that stored lowest value associated with a key, assumes that it has permission to write and goes ahead with compare-and-swap for desired record, then deletes its entry from the lock DB, other threads simply retry.
The scenario is something like this description.
I've the typical mysql table for the users storage, currently, the user ID is one integer set as autoincrement. Very much of the API rest interfaces works with the user alias (that's unique) to find the user, then, I'm thinking implement the user ID with the alias.hashcode() (that's one integer) to find diretly for ID every times.
Is a good idea implement Mysql ID with one java String hashcode?. Would enhance the performance?
I don't think it's a great idea. The pigeon hole principle states (from Wikipedia) if n items are put into m containers, with n > m, then at least one container must contain more than one item. Basically, your solution cannot handle collisions and collisions are very possible with hashing.
Don't use String hashCode as your ID, since it's not unique. Two different Strings may have the same hashCode. I'm assuming your ID should be unique.
Just add an index on the alias column, and query the db by alias directly. There are two problems with using alias hash code or other derivatives as an id. First, as others pointed out, hash codes are not be unique (this can be almost solved by changing the id type to string, and using a digest instead of the hash. Collisions with digests, while still possible, are extremely unlikely). Second, if the user changes his alias, the value will get out of sync with the id. If functionality of your application is such, that this situation is either impossible or unimportant, then you don't really need an id at all, and can identify users by alias directly.
I have a MultiValueMap like
{3=[c-2, c-2], 2=[b-1, b-1], 1=[a-1, a-2, a-3]}
At one point I have to update a single value of a specific key
for example I have to update the key 2 like
2=[u-1,u-2]
how can i do this?
I've never used that library - but I would expect these two examples to do what you need:
multiMap.getCollection(2).clear();
multiMap.putAll(2, Arrays.asList("u-1", "u-2"));
Or
Collection c = multiMap.getCollection(2);
c.clear();
Collections.addAll(c, "u-1", "u-2");
The safest way is to call getCollection() to retrieve the current mapping, remove(key) to clear that mapping, iterate the retrieved collection to re-insert values that you want to keep, and/or add the new values.
If you know the type of collection used for a mapping (because you've called the constructor that takes collectionFactory), you could get the collection and update it directly.
I have some java code which returns me a map, and I want to access this in XSLT.
I just saved the result in some variable called $map.
Tried accessing the value as key($map,'key1') with no luck.
where $map is what some java method returned and key1 is the key of one map entry.
I want to fetch its value.
Any suggestions ?