/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* JBoss, Home of Professional Open Source
* Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors
* as indicated by the @authors tag. All rights reserved.
* See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License, v. 2.1.
* This program is distributed in the hope that it will be useful, but WITHOUT A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License,
* v.2.1 along with this distribution; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.hibernate.ogm.test.mongodb.loading;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import org.hibernate.cfg.Configuration;
import org.hibernate.ogm.datastore.mongodb.AssociationStorage;
import org.hibernate.ogm.datastore.mongodb.Environment;
import org.hibernate.ogm.grid.AssociationKind;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.ogm.datastore.impl.DatastoreServices;
import org.hibernate.ogm.datastore.mongodb.impl.MongoDBDatastoreProvider;
import org.hibernate.ogm.datastore.spi.Association;
import org.hibernate.ogm.datastore.spi.AssociationContext;
import org.hibernate.ogm.datastore.spi.DatastoreProvider;
import org.hibernate.ogm.datastore.spi.Tuple;
import org.hibernate.ogm.datastore.spi.TupleContext;
import org.hibernate.ogm.dialect.GridDialect;
import org.hibernate.ogm.dialect.mongodb.MongoDBAssociationSnapshot;
import org.hibernate.ogm.dialect.mongodb.MongoDBDialect;
import org.hibernate.ogm.grid.AssociationKey;
import org.hibernate.ogm.grid.EntityKey;
import org.hibernate.ogm.test.simpleentity.OgmTestCase;
import org.hibernate.service.Service;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import static org.fest.assertions.Assertions.assertThat;
/**
* @author Guillaume Scheibel<guillaume.scheibel@gmail.com>
*/
public class LoadSelectedColumnsCollectionTest extends OgmTestCase {
@Test
public void testLoadSelectedColumns() {
final String collectionName = "Drink";
MongoDBDatastoreProvider provider = (MongoDBDatastoreProvider) this.getService( DatastoreProvider.class );
DB database = provider.getDatabase();
DBCollection collection = database.getCollection( collectionName );
BasicDBObject water = new BasicDBObject();
water.put( "_id", "1234" );
water.put( "name", "Water" );
water.put( "volume", "1L" );
collection.insert( water );
List<String> selectedColumns = new ArrayList<String>();
selectedColumns.add( "name" );
Tuple tuple = this.getTuple( collectionName, "1234", selectedColumns );
assertNotNull( tuple );
Set<String> retrievedColumn = tuple.getColumnNames();
/*
*The dialect will return all columns (which include _id field) so we have to substract 1 to check if
*the right number of columns has been loaded.
*/
assertEquals( selectedColumns.size(), retrievedColumn.size() - 1 );
assertTrue( retrievedColumn.containsAll( selectedColumns ) );
collection.remove( water );
}
@Test
public void testLoadSelectedAssociationColumns() {
Session session = openSession();
final Transaction transaction = session.getTransaction();
transaction.begin();
Module mongodb = new Module();
mongodb.setName( "MongoDB" );
session.persist( mongodb );
Module infinispan = new Module();
infinispan.setName( "Infinispan" );
session.persist( infinispan );
List<Module> modules = new ArrayList<Module>();
modules.add( mongodb );
modules.add( infinispan );
Project hibernateOGM = new Project();
hibernateOGM.setId( "projectID" );
hibernateOGM.setName( "HibernateOGM" );
hibernateOGM.setModules( modules );
session.persist( hibernateOGM );
transaction.commit();
this.addExtraColumn();
GridDialect gridDialect = this.getGridDialect();
AssociationKey associationKey = new AssociationKey(
"Project_Module",
new String[] { "Project_id" },
new Object[] { "projectID" }
);
associationKey.setAssociationKind( AssociationKind.ASSOCIATION );
associationKey.setCollectionRole( "modules" );
associationKey.setOwnerEntityKey( new EntityKey( "Project", new String[] { "id" }, new String[] { "projectID" } ) );
associationKey.setRowKeyColumnNames( new String[]{"Project_id", "module_id"} );
AssociationContext associationContext = new AssociationContext( Arrays.asList( associationKey.getRowKeyColumnNames() ) );
final Association association = gridDialect.getAssociation( associationKey, associationContext );
final MongoDBAssociationSnapshot associationSnapshot = (MongoDBAssociationSnapshot) association.getSnapshot();
final DBObject assocObject = associationSnapshot.getDBObject();
this.checkLoading(assocObject);
session.delete( mongodb );
session.delete( infinispan );
session.delete( hibernateOGM );
session.close();
}
public Tuple getTuple(String collectionName, String id, List<String> selectedColumns){
EntityKey key = new EntityKey( collectionName, new String[] { MongoDBDialect.ID_FIELDNAME }, new Object[] { id } );
TupleContext tupleContext = new TupleContext( selectedColumns );
return this.getGridDialect().getTuple( key, tupleContext );
}
protected Service getService(Class<? extends Service> serviceImpl){
SessionFactoryImplementor factory = super.sfi();
ServiceRegistryImplementor serviceRegistry = factory.getServiceRegistry();
return serviceRegistry.getService( serviceImpl );
}
protected GridDialect getGridDialect(){
return ( (DatastoreServices) this.getService( DatastoreServices.class ) ).getGridDialect();
}
@Override
protected void configure(Configuration cfg) {
super.configure( cfg );
cfg.setProperty(
Environment.MONGODB_ASSOCIATIONS_STORE,
AssociationStorage.COLLECTION.toString().toLowerCase()
);
}
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Project.class,
Module.class
};
}
/**
* To be sure the datastoreProvider retrieves only the columns we want,
* an extra column is manually added to the association document
*/
protected void addExtraColumn(){
MongoDBDatastoreProvider provider = (MongoDBDatastoreProvider) this.getService( DatastoreProvider.class );
DB database = provider.getDatabase();
DBCollection collection = database.getCollection( "associations_Project_Module" );
BasicDBObject query = new BasicDBObject( 1 );
query.put( "_id", new BasicDBObject( "Project_id", "projectID" ) );
BasicDBObject updater = new BasicDBObject( 1 );
updater.put( "$push", new BasicDBObject( "extraColumn", 1 ) );
collection.update( query, updater );
}
protected void checkLoading(DBObject associationObject) {
/*
* The only column (except _id) that needs to be retrieved is "rows"
* So we should have 2 columns
*/
final Set<?> retrievedColumns = associationObject.keySet();
assertThat( retrievedColumns ).hasSize( 2 ).containsOnly( MongoDBDialect.ID_FIELDNAME, MongoDBDialect.ROWS_FIELDNAME );
}
}