how will spring mongodbtemplate check if object already exists - mongodb

I am using save method in mongdbtemplate of spring mongo(api link provided below).
http://static.springsource.org/spring-data/mongodb/docs/1.2.x/api/org/springframework/data/mongodb/core/MongoTemplate.html#save(java.lang.Object, java.lang.String)
I am trying to understand how will mongdbtemplate check if object is already existing.
I am assuming the it uses equals method on object passed, please let me know if it is otherwise

There is no magic code that mongodbtemplate uses internally. MongoDB natively supports the concept of upsert.

Related

Access to Bind Parameters in MyBatis Interceptor

How do I read the bind parameters inside a MyBatis Interceptor? I'm trying to extract those information so I can write them to a log table.
The guide (http://www.mybatis.org/mybatis-3/configuration.html) didn't mention how to get them, and the JavaDoc (http://www.mybatis.org/mybatis-3/es/apidocs/org/apache/ibatis/mapping/BoundSql.html) does not have a single line of comment. I saw an example on SO about constructing a new BoundSql but that isn't what I needed.
I tried to test what contents are stored in BoundSql.getParameterMappings() and BoundSql.getParameterObject(), but it seems to be pretty complex. There's JavaType and JdbcType, and if there's only one parameter the ParameterObject isn't a Map object.
What is the proper way to get the bind parameters from BoundSql?
After going through MyBatis source code (where comment is an endangered species), I found out how MyBatis processes the bind parameters. However, that requires access to the JDBC Statement object, which is simply not available inside an Interceptor.
Then I did some testing and settled on this:
If there is only a single parameter, BindSql.getParameterObject() will give you the parameter itself. By using BindSql.getParameterMappings() and ParameterMapping.getJavaType() I can tell which Java class the parameter is.
If there are more than one parameter, BindSql.getParameterObject() will return an instance of org.apache.ibatis.binding.MapperMethod.ParamMap, which extends HashMap, or it will be an instance of the DTO you used. Using .getProperty() from ParameterMapping as key or as getter name, you can process the bind parameters one by one.
If anyone has a better way to do this, I'm all ears.

How do I detect whether a mongodb serializer is already registered?

I have created a custom serializer for mongoDB.
I can register it and it works as expected.
However the my application sometimes throws an error because it tries to register the serializer twice.
How do I detect whether a serializer has already been registered and thus stop my application from registering a second time?
If you are using
BsonSerializer.RegisterSerializer(typeof (Type), typeSerializer);
you might get this error "there is already a serializer registered for type". Because you cannot register the same type of serializer 2 times. But you can write your own serializer and this serializer will work before default serializers.
For instance: if you want to use local DateTime instead of Utc which is default.
all you need to do is that writing a class implementing IBsonSerializationProviderand register this provider to BsonSerializer as soon as possible!
here is the sample code.
public class LocalDateTimeSerializationProvider : IBsonSerializationProvider
{
public IBsonSerializer GetSerializer(Type type)
{
return type == typeof(DateTime) ? DateTimeSerializer.LocalInstance : null;
}
}
and to be able to register
BsonSerializer.RegisterSerializationProvider(new LocalDateTimeSerializationProvider());
I hope this helps, you can also read the original documentation in here
this .net driver version of mongodb is 2.4!
TL;DR: Ig you are lazy, use BsonSerializer.LookupSerializer or BsonMemberMap.GetSerializer. To do it right, make sure the registration code is called once and only once.
The best approach to avoid this is to make sure the serializer is registered only once. It's a good idea to have some global startup code that registers anything that is global to the application once, and only once. That includes stuff like dependency injector configuration, tools like automapper and the mongodb driver. If you call this code only once and from a single point in code, you don't need to worry about thread safety, dead locks or similar troubles.
The MongoDB driver configuration settings are thread-safe, but don't assume that this is true for all software packages that you might need to configure. Also, locking can be very expensive performance wise if your code is multi-threaded, for instance in a web-application. Last but not least, that lookup you're doing might not be trivial in the first place, because some methods need to walk an entire inheritance tree.

What is the MyBatis equivalent to the Ibatis update(String, Object, int) method?

There is an update method in iBatis SqlMapClientTemplate that allows to specify how many rows are expected to be updated (and throws exception if this is not matched).
Is there any equivalent to this method in MyBatis' sqlSession? Those docs suggest there isn't.
What is the best way to implement such a check the other way?
There's no such equivalent method in mybatis' spring extension
http://mybatis.github.io/spring/apidocs/reference/org/mybatis/spring/SqlSessionTemplate.html
Maybe you can raise it as an issue or submit as a pull request to the team :P
Just came back to that question and realized that it was really trivial.
Source code of iBatis' overloaded update just calls the regular update(String, Object) and checks returned value.
As myBatis also has update(String, Object), this can be simply implemented the same way.
Simplicity of this method was probably the reason to drop its support in myBatis.

RequestFactory's Entity Relationships

The details of the Request's with() implementation of RequestFactory in GWT is a bit unclear to me. See here for the official documentation.
Question 1:
When querying the server, RequestFactory does not automatically
populate relations in the object graph. To do this, use the with()
method on a request and specify the related property name as a String.
Does this mean that if the Entity at the server uses Lazy Fetching, the returned EntityProxy will have all the requested objects specified in with()? It seems a bit odd to instantiate the whole object graph of the Object server side, to only send a small piece to the client.
Question 2:
Does req.with("foo").with("foo"); do the same as req.with("foo"); ?
Question 3:
Does req.with("foo").with("bar"); do the same as req.with("foo","bar"); ?
NOTE: I'm having a really hard time finding the implementation details of with() in the source code and the API doesn't help me either.
Question 1:
It probably depends on your server side implemenation.
The with invocation will only make sure that the corresponding getter (getFoo()) is called shortly before the RF call returns to the client.
That's the reason why you also have to make sure to use an OpenSessionInView pattern, otherwise you might run into NullPointeterExceptions.
Question 2:
I guess the Request<T> implements a builder pattern.
The end-result will be the same.
However I am not sure if the getter() will be called twice or if the with method will check if the getter is already requested.
Question 3:
Yes it's the same.
As a sidenote. You can use req.with("foo.bar").
On the backend this will lead to a getFoo().getBar() call.

GWT request .with method

I'm sorry in advance if this rather n00bish question actually has an answer in the documentation which I've just failed to find, but
I'm still relatively new to GWT, and try as I might I can't find an explanation of what the request.with(String...) method actually does which I can understand. Please can someone explain to me in words of one sylable what this method does and why you'd use it?
thanks very much
It indeed is in the doc: https://developers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory#relationships
By default, entity proxies referenced from the entity proxy/ies you're fetching are not fetched (properties will simply be null on the client-side). You have to explicitly ask for them using with(), passing the name (can be a dotted path too) of the properties you want to fetch.