Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

May 25, 2016

MongoBulkItemWriter

Spring Batch is a nice choice for simple ETL jobs, but it doesn't work well with mongodb, especially writing to it. Provided in Spring Batch MongoItemWriter doesn't do bulk inserts.
Fortunately for us, bulk inserts are quite easy to implement:
import com.mongodb.BulkWriteOperation;
import com.mongodb.BulkWriteResult;
import com.mongodb.DBObject;
import org.springframework.batch.item.ItemWriter;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.List;

public class MongoBulkItemWriter<T> implements ItemWriter<T> {

    private String collection;
    private MongoTemplate template;

    public MongoBulkItemWriter(String collection, MongoTemplate mongoTemplate) {
        this.collection = collection;
        this.template = mongoTemplate;
    }

    @Override
    public void write(List items) throws Exception {
        BulkWriteOperation bulk = template.getCollection(collection).initializeUnorderedBulkOperation();
        items.forEach(i->{
                bulk.insert((DBObject) template.getConverter().convertToMongoType(i));
        });
        BulkWriteResult result = bulk.execute();
    }
}
It works much faster, but beware - inserts only, so item with duplicate id will ruin your batch. Solution might look something like this:
        BulkWriteOperation bulk = template.getCollection(COLLECTION_NAME).initializeUnorderedBulkOperation();
        updates.forEach(u -> {
            bulk.find(new BasicDBObject("id", u.getId())).upsert().update(u.getDbObject());
        });
        bulk.execute();
Upserts are much slower than pure inserts, but still a huge win compared with per object writes.

Jan 15, 2016

OOP - we are fooling ourselves

Object Oriented Programming is a holy grail of modern code-writing methodologies. As everything so fundamental, it was criticised  quite heavily, with different degree of details. Some say, OOP is dead, some say it’s harmful. I think, we should reconsider our understanding of this paradigm.
If we talk about objects - we think about state (a lot) and behaviour (a little) . But in all domain models  we separate between «domain» and «business» logic. 

Example: A human buys bananas in a grocery store. Here set of objects Bananas change ownership and location. Object Store obtains money, frees some space in a shop, and loose some bananas. Object human looses money and gets a bananas. 
Question: What object should own this logic? If it’s 3 different objects, each with it’s own functions, then who should coordinate behaviour? Is it a shop who should take money from a human and change ownership of bananas? Or Human? Or Banana? Or some different different Object?
In practice, usually it’s different object, most probably StoreService. 

After that we have another question - about persistence. Somebody should store it to a database (persistent storage). Should it be domain objects? In practice, it’s usually DAO layer. 
And I will not dig into details - because human usually need to pack bananas in a bag and store should manage not to run out of bananas.
So, what do we have here - our objects are passive data objects, and all behaviour is in other objects, with some dependency on external resources (database).

Is it OOP ? Well, in practice, it’s what everybody calls OOP. Clearly, something is wrong.
Looking on a Store, we will not have an idea about all it’s abilities. StoreService will give us much more information. 

There is one solution I know to this problem - mix-ins. You will be able to mix some resource-dependent behaviour into domain objects, without altering domain objects much. Is it OOP ?
Nice articles on a subject:

Oct 1, 2007

How to write javadoc

My personal opinion how to write good javadocs (with examples from jdk)

Overview of method/class

Goal of method/class ? What is goal of class. Example:
* The <code>String</code> class represents character strings. All
* string literals in Java programs, such as <code>"abc"</code>, are
* implemented as instances of this class.

Responsibility of method/class ?What method/class is doing. Example in code above.

Action of method ?What statements we can make about how goal is achieved ? Example in StringBuffer class.
/**
* Ensures that the capacity of the buffer is at least equal to the
* specified minimum.
* If the current capacity of this string buffer is less than the
* argument, then a new internal buffer is allocated with greater
* capacity. The new capacity is the larger of:
* <ul>
* <li>The <code>minimumCapacity</code> argument.
* <li>Twice the old capacity, plus <code>2</code>.
* </ul>
* If the <code>minimumCapacity</code> argument is nonpositive, this
* method takes no action and simply returns.
*
* @param minimumCapacity the minimum desired capacity.
*/
public synchronized void ensureCapacity(int minimumCapacity) {

And, of course, describe boundary situations carefully.

Preconditions of method:

Some special agreement then it's legal to apply method/class, example:
* @param s a <code>String</code> containing the <code>int</code>
* representation to be parsed

It's not necessary must be placed in params, but it's good to have such statement. ;)

Postconditions of method:

What it must return if everything is ok.
* @return the integer value represented by the argument in decimal.

Exceptions documentation:

Please don't provide javadoc like "throws Exception if something goes wrong", it has no information in it.
Good Example is:
* @exception NumberFormatException if the string does not contain a
* parsable integer.

CRC description of class

Class javadoc is good then it contains Overview of class, it's responsibilities, classes it coolaborates with, and brief description of working logic and purpose. Example from Timer class.
/**
* A facility for threads to schedule tasks for future execution in a
* background thread. Tasks may be scheduled for one-time execution, or for
* repeated execution at regular intervals.

Examples of use helps a lot sometimes.

Links:

java.sun.com/j2se/javadoc/writingdoccomments/

alistair.cockburn.us/index.php/Structuring_use_cases_with_goals

en.wikipedia.org/wiki/Design_by_contract