This is an example for future reference and I'm not going to comment futher on it than what's already in the comments.
package experiment.morphia;
import org.bson.types.ObjectId;
import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Id;
@Entity
public class Location
{
@Id
private ObjectId id;
private Integer stars;
private String street;
private String city;
private String state;
private String zipcode;
private String country;
public Location() {}
public Location( Integer stars, String street, String city, String state, String zipcode, String county )
{
this.stars = stars;
this.street = street;
this.city = city;
this.state = state;
this.zipcode = zipcode;
this.country = county;
}
public ObjectId getId() { return this.id; }
public void setId( ObjectId id ) { this.id = id; }
public Integer getStars() { return this.stars; }
public void setStars( Integer stars ) { this.stars = stars; }
public String getStreet() { return this.street; }
public void setStreet( String street ) { this.street = street; }
public String getCity() { return this.city; }
public void setCity( String city ) { this.city = city; }
public String getState() { return this.state; }
public void setState( String state ) { this.state = state; }
public String getZipcode() { return this.zipcode; }
public void setZipcode( String zipcode ) { this.zipcode = zipcode; }
public String getCountry() { return this.country; }
public void setCountry( String country ) { this.country = country; }
public String toString()
{
String string = "";
if( this.id != null )
string = "[" + this.id + "] ";
if( this.stars != 1 )
string += this.stars + " stars ";
else
string += this.stars + " star ";
string += this.street + " "
+ this.city + " ";
if( this.state != null )
string += this.state + " ";
string += this.country + " "
+ this.zipcode;
return string;
}
}
package experiment.morphia;
import java.util.ArrayList;
import org.bson.types.ObjectId;
import com.google.code.morphia.annotations.Embedded;
import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Id;
@Entity( noClassnameStored=true )
public class Hotel
{
@Id
private ObjectId id;
private String name;
private int stars;
public Hotel() {}
public Hotel( String name, int stars )
{
this.name = name;
this.stars = stars;
}
@Embedded
private ArrayList< Location > locations;
public ObjectId getId() { return id; }
public void setId( ObjectId id ) { this.id = id; }
public String getName() { return name; }
public void setName( String name ) { this.name = name; }
public int getStars() { return stars; }
public void setStars( int stars ) { this.stars = stars; }
public ArrayList< Location > getLocations() { return locations; }
public void setLocations( ArrayList< Location > locations ) { this.locations = locations; }
public String toString()
{
String string = this.name + ", " + this.stars + " stars " + "[" + this.id + "]\n";
for( Location location : this.locations )
string += " " + location.toString() + "\n";
return string;
}
}
package experiment.morphia;
import java.util.List;
import util.Implementor;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.dao.BasicDAO;
/**
* Do database stuff here...
*/
@Implementor( HotelDao.class )
public class HotelDao extends BasicDAO< Hotel, String >
{
/* The Datastore is a wrapper around the MongoDB Java driver and is used to manage
* entities in MongoDB.
*/
Datastore datastore; // inject this manually for now...
public HotelDao()
{
super( HotelTest.getMongo(), HotelTest.getMorphia(), "hotels" );
this.datastore = HotelTest.getDatastore();
}
public Hotel create( Hotel hotel )
{
this.datastore.save( hotel );
return hotel;
}
public List< Hotel > read()
{
return this.datastore.find( Hotel.class ).asList();
}
public List< Hotel > read( String query, String value )
{
if( query == null && value == null )
return this.datastore.find( Hotel.class ).asList();
return this.datastore.find( Hotel.class, query, value ).asList();
}
public List< Hotel > read( String query, Integer value )
{
if( query == null && value == null )
return this.datastore.find( Hotel.class ).asList();
return this.datastore.find( Hotel.class, query, value ).asList();
}
public void update( Hotel hotel )
{
this.datastore.merge( hotel );
}
public void remove( Hotel hotel )
{
this.datastore.delete( hotel );
}
}
package experiment.morphia;
import java.util.List;
import util.Implementor;
import util.ServiceLocator;
/**
* Do business logic here...
*/
@Implementor( HotelManager.class )
public class HotelManager
{
private HotelDao hotelDao = ServiceLocator.get( HotelDao.class );
public Hotel create( Hotel hotel )
{
return hotelDao.create( hotel );
}
public List< Hotel > read()
{
return hotelDao.read();
}
public List< Hotel > read( String query, String value )
{
return hotelDao.read( query, value );
}
public List< Hotel > read( String query, Integer value )
{
return hotelDao.read( query, value );
}
public void update( Hotel hotel )
{
hotelDao.update( hotel );
}
public void delete( Hotel hotel )
{
hotelDao.remove( hotel );
}
}
package experiment.morphia;
import java.util.List;
import util.ServiceLocator;
/**
* Do web service here (except that this isn't a web service, but a squirrel cage)...
*/
public class HotelService
{
private HotelManager hotelManager = ServiceLocator.get( HotelManager.class );
public Hotel create( Hotel hotel )
{
return this.hotelManager.create( hotel );
}
public List< Hotel > read()
{
return this.hotelManager.read();
}
public List< Hotel > read( String query, String value )
{
return this.hotelManager.read( query, value );
}
public List< Hotel > read( String query, Integer value )
{
return this.hotelManager.read( query, value );
}
public void update( Hotel hotel )
{
this.hotelManager.update( hotel );
}
public void delete( Hotel hotel )
{
this.hotelManager.delete( hotel );
}
}
package experiment.morphia;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.apache.log4j.Logger;
import util.ServiceLocator;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
@SuppressWarnings( "unused" )
public class HotelTest
{
public static Logger log = Logger.getLogger( HotelTest.class );
private static Mongo mongodb;
private static DB database;
private static Morphia morphia;
private static Datastore datastore;
private static final String DATABASE_NAME = "hotels";
private static final String HOTEL_NAME = "Hotel Hyatt";
private static final String COLLECTION_NAME = Hotel.class.getSimpleName();
public static Mongo getMongo() { return mongodb; }
public static Morphia getMorphia() { return morphia; }
public static Datastore getDatastore() { return datastore; }
/**
* Initialize MongoDB and Morphia for our purposes.
*/
private static void initializeMongoAndMorphia()
{
try
{
mongodb = new Mongo( "localhost", 27017 );
}
catch( UnknownHostException e )
{
log.error( "MongoDB host not found" );
}
catch( MongoException e )
{
log.error( "Error attempting MongoDB connection for hotels", e );
}
database = mongodb.getDB( DATABASE_NAME );
morphia = new Morphia();
datastore = morphia.createDatastore( mongodb, DATABASE_NAME );
database.dropDatabase(); // drop any fodder left in from last time...
morphia.map( Hotel.class ).map( Location.class );
}
/**
* Clean up the document we put in here last time (works assuming the hotel name hasn't
* changed) so that we start fresh.
*
* @param key field name ("name").
* @param value hotel name.
*/
private static void deleteDocumentFromCollection( String key, String value )
{
DBCollection collection = database.getCollection( COLLECTION_NAME );
try
{
BasicDBObject dbo = new BasicDBObject();
dbo.append( key, value );
collection.remove( dbo );
}
catch( MongoException e )
{
log.debug( "Ignored: " + e.getMessage() );
}
}
public static void main( String[] args )
{
initializeMongoAndMorphia();
HotelService service = new HotelService();
// CREATE
/* Create a random number of hotel chains and put them into the database.
*/
Long milliseconds = System.currentTimeMillis();
Random generator = new Random( milliseconds );
int hotelsCount = HotelFodder.getHotelCount();
// always ensure we've got at least one hotel chain...
int which = generator.nextInt( hotelsCount );
if( which == 0 )
which = 1;
if( which == 1 )
System.out.println( "Creating a hotel chain..." );
else
System.out.println( "Creating " + which + " hotel chains..." );
while( which > 0 )
{
Hotel h = service.create( HotelFodder.newHotel() );
which--;
}
/* If I move the stars to the individual locations, I query this way:
* > db.Hotel.find( { "locations" : { $elemMatch : { "stars" : { $gt : 2 } } } } ).count();
* However, this still gives me back the whole Hotel document including the lesser-star
* hotel locations.
*
* This came up as I was assigning stars to locations instead of hotel chains. I stopped
* short of extending this change to what's going on here since it's isn't relevant and I
* don't want to continue to play with it.
*/
// READ
List< Hotel > fourStarChains = service.read( "stars >", 2 );
System.out.println( "Looking for 3-star or better hotels..." );
Hotel h_c = null;
int count = 0;
for( Hotel hc : fourStarChains )
{
System.out.println( hc );
count++;
}
if( count == 0 )
System.out.println( "(There were no 3-star or better hotels.)" );
}
}
package experiment.morphia;
public class HotelTuple
{
String hotelName;
Integer stars;
public HotelTuple( String name, Integer stars )
{
this.hotelName = name;
this.stars = stars;
}
}
package experiment.morphia;
import java.util.ArrayList;
import java.util.Random;
public class HotelFodder
{
private static boolean once = false;
private static Random generator1;
private static Random generator2;
private static Random generator3;
private static ArrayList< Location > locations;
private static ArrayList< HotelTuple > hotelNamesAndStars;
private static void initializeAddresses()
{
locations = new ArrayList< Location >();
locations.add( new Location( 2, "3222 South 525 West", "Bountiful", "UT", "84101", "US" ) );
locations.add( new Location( 2, "59, rue Albert Premier", "Bezons", null, "95057", "FR" ) );
locations.add( new Location( 4, "Miquelallee Straß, 23", "Frankfurt", null, "65936", "DE" ) );
locations.add( new Location( 1, "1313 Mockingbird Lane", "Mockingbird Heights", "CA", "06660", "US" ) );
locations.add( new Location( 5, "12345 Bedford Drive", "Beverly Hills", "CA", "90210", "US" ) );
locations.add( new Location( 4, "1778 Oregon Avenue", "Provo", "UT", "84606", "US" ) );
locations.add( new Location( 4, "23, rue du Puits", "Pagny-la-Blanche-Côte", null, "55010", "FR" ) );
locations.add( new Location( 4, "48 Cicada Drive", "Boise", "ID", "83702", "US" ) );
locations.add( new Location( 5, "5, Boulevard des Capucines", "Paris", null, "75008", "FR" ) );
}
private static void initializeHotelNamesAndStars()
{
hotelNamesAndStars = new ArrayList< HotelTuple >();
hotelNamesAndStars.add( new HotelTuple( "Hyatt Hotel", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Bayside Arms", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Hotel California", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Bates Motel", 0 ) );
hotelNamesAndStars.add( new HotelTuple( "Purple Hives", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Sofitel", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Novotel", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Marriott Courtyard", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Holiday Inn", generator3.nextInt( 5 ) + 1 ) );
hotelNamesAndStars.add( new HotelTuple( "Embassey Suites", generator3.nextInt( 5 ) + 1 ) );
}
public static void initializeFodder()
{
Long milliseconds = System.currentTimeMillis();
if( once )
return;
generator1 = new Random( milliseconds );
generator2 = new Random( milliseconds + 89 );
generator3 = new Random( milliseconds + 76 );
initializeAddresses();
initializeHotelNamesAndStars();
once = true;
}
public static int getLocationCount()
{
initializeFodder();
return locations.size();
}
public static int getHotelCount()
{
initializeFodder();
return hotelNamesAndStars.size();
}
/**
* Generate a new hotel chain with a random name, stars and set of locations.
*
* @return one new Hotel chain.
*/
public static Hotel newHotel()
{
initializeFodder();
int locationCount = getLocationCount();
int hotelCount = getHotelCount();
HotelTuple tuple = hotelNamesAndStars.get( generator1.nextInt( hotelCount ) );
Hotel hotel = new Hotel( tuple.hotelName, tuple.stars );
ArrayList< Location > as = new ArrayList< Location >();
// always ensure we've got at least one location in a hotel chain...
int howMany = generator2.nextInt( locationCount );
if( howMany == 0 )
howMany = 1;
int next = generator3.nextInt( locationCount );
while( howMany > 0 )
{
if( next < 0 )
next = locationCount - 1;
Location location = locations.get( next );
as.add( location );
howMany--;
next--;
}
hotel.setLocations( as );
return hotel;
}
public static void main( String[] args )
{
Hotel hotel = newHotel();
System.out.println( hotel.toString() );
}
}