Skip to content

Instantly share code, notes, and snippets.

@pavel-drabushevich
Created January 18, 2012 07:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pavel-drabushevich/1631780 to your computer and use it in GitHub Desktop.
Save pavel-drabushevich/1631780 to your computer and use it in GitHub Desktop.
@XmlRootElement
@Document(collection = "user")
@PersistenceCapable
@View
public class User {
@Id
@JsonIgnore(true)
private String id;
private String username;
}
@XmlRootElement
@Document(collection = "user")
@PersistenceCapable
public class UserAuth extends User {
private String password;
}
@XmlRootElement
@Document(collection = "user")
@PersistenceCapable
public class UserContact extends User {
private String email;
private String phone;
private String address;
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface View {
}
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import org.springframework.data.authentication.UserCredentials;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.convert.MongoWriter;
import org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent;
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveEvent;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import java.util.Map;
public class ViewMongoTemplate extends MongoTemplate {
private static final String ID_FIELD = "_id";
private static final String CLASS_FIELD = "_class";
public ViewMongoTemplate(Mongo mongo, String databaseName) {
super(mongo, databaseName);
}
public ViewMongoTemplate(Mongo mongo, String databaseName, UserCredentials userCredentials) {
super(mongo, databaseName, userCredentials);
}
public ViewMongoTemplate(MongoDbFactory mongoDbFactory) {
super(mongoDbFactory);
}
public ViewMongoTemplate(MongoDbFactory mongoDbFactory, MongoConverter mongoConverter) {
super(mongoDbFactory, mongoConverter);
}
@Override
public void save(Object objectToSave, String collectionName) {
if (objectToSave.getClass().isAnnotationPresent(View.class)) {
doViewSave(collectionName, objectToSave, super.getConverter());
} else {
super.save(objectToSave, collectionName);
}
}
protected <T> void doViewSave(final String collectionName, final T objectToSave,
final MongoWriter<T> writer) {
final BasicDBObject dbDoc = new BasicDBObject();
maybeEmitEvent(new BeforeConvertEvent<T>(objectToSave));
writer.write(objectToSave, dbDoc);
// remove class field, views collection have many classes
dbDoc.remove(CLASS_FIELD);
final Object idValue = getDBObjectIdValue(dbDoc);
if (idValue == null) {
saveNewEntity(collectionName, objectToSave, dbDoc);
} else {
updateViewEntity(collectionName, objectToSave, dbDoc, idValue);
}
}
private <T> void updateViewEntity(String collectionName, T objectToSave, BasicDBObject dbDoc, Object idValue) {
final Query query = new Query().addCriteria(new Criteria(ID_FIELD).is(idValue));
final Update update = new Update();
for (Map.Entry<String, Object> entry : dbDoc.entrySet()) {
final String field = entry.getKey();
if (ID_FIELD.equals(field)) {
continue;
}
final Object value = entry.getValue();
if (value == null) {
continue;
}
update.set(field, value);
}
// may check result
doUpdate(collectionName, query, update, objectToSave.getClass(), true, false);
}
private <T> void saveNewEntity(String collectionName, T objectToSave, BasicDBObject dbDoc) {
maybeEmitEvent(new BeforeSaveEvent<T>(objectToSave, dbDoc));
final Object id = saveDBObject(collectionName, dbDoc, objectToSave.getClass());
populateIdIfNecessary(objectToSave, id);
maybeEmitEvent(new AfterSaveEvent<T>(objectToSave, dbDoc));
}
private Object getDBObjectIdValue(final DBObject dbDoc) {
return dbDoc.get(ID_FIELD);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment