This is an example for future reference and I'm not going to comment futher on it than what's already in the comments.
01.
package
experiment.morphia;
02.
03.
import
org.bson.types.ObjectId;
04.
05.
import
com.google.code.morphia.annotations.Entity;
06.
import
com.google.code.morphia.annotations.Id;
07.
08.
@Entity
09.
public
class
Location
10.
{
11.
@Id
12.
private
ObjectId id;
13.
14.
private
Integer stars;
15.
private
String street;
16.
private
String city;
17.
private
String state;
18.
private
String zipcode;
19.
private
String country;
20.
21.
public
Location() {}
22.
23.
public
Location( Integer stars, String street, String city, String state, String zipcode, String county )
24.
{
25.
this
.stars = stars;
26.
this
.street = street;
27.
this
.city = city;
28.
this
.state = state;
29.
this
.zipcode = zipcode;
30.
this
.country = county;
31.
}
32.
33.
public
ObjectId getId() {
return
this
.id; }
34.
public
void
setId( ObjectId id ) {
this
.id = id; }
35.
36.
public
Integer getStars() {
return
this
.stars; }
37.
public
void
setStars( Integer stars ) {
this
.stars = stars; }
38.
public
String getStreet() {
return
this
.street; }
39.
public
void
setStreet( String street ) {
this
.street = street; }
40.
public
String getCity() {
return
this
.city; }
41.
public
void
setCity( String city ) {
this
.city = city; }
42.
public
String getState() {
return
this
.state; }
43.
public
void
setState( String state ) {
this
.state = state; }
44.
public
String getZipcode() {
return
this
.zipcode; }
45.
public
void
setZipcode( String zipcode ) {
this
.zipcode = zipcode; }
46.
public
String getCountry() {
return
this
.country; }
47.
public
void
setCountry( String country ) {
this
.country = country; }
48.
49.
public
String toString()
50.
{
51.
String string =
""
;
52.
53.
if
(
this
.id !=
null
)
54.
string =
"["
+
this
.id +
"] "
;
55.
56.
if
(
this
.stars !=
1
)
57.
string +=
this
.stars +
" stars "
;
58.
else
59.
string +=
this
.stars +
" star "
;
60.
61.
string +=
this
.street +
" "
62.
+
this
.city +
" "
;
63.
64.
if
(
this
.state !=
null
)
65.
string +=
this
.state +
" "
;
66.
67.
string +=
this
.country +
" "
68.
+
this
.zipcode;
69.
70.
return
string;
71.
}
72.
}
01.
package
experiment.morphia;
02.
03.
import
java.util.ArrayList;
04.
05.
import
org.bson.types.ObjectId;
06.
07.
import
com.google.code.morphia.annotations.Embedded;
08.
import
com.google.code.morphia.annotations.Entity;
09.
import
com.google.code.morphia.annotations.Id;
10.
11.
@Entity
( noClassnameStored=
true
)
12.
public
class
Hotel
13.
{
14.
@Id
15.
private
ObjectId id;
16.
17.
private
String name;
18.
private
int
stars;
19.
20.
public
Hotel() {}
21.
22.
public
Hotel( String name,
int
stars )
23.
{
24.
this
.name = name;
25.
this
.stars = stars;
26.
}
27.
28.
@Embedded
29.
private
ArrayList< Location > locations;
30.
31.
public
ObjectId getId() {
return
id; }
32.
public
void
setId( ObjectId id ) {
this
.id = id; }
33.
34.
public
String getName() {
return
name; }
35.
public
void
setName( String name ) {
this
.name = name; }
36.
37.
public
int
getStars() {
return
stars; }
38.
public
void
setStars(
int
stars ) {
this
.stars = stars; }
39.
40.
public
ArrayList< Location > getLocations() {
return
locations; }
41.
public
void
setLocations( ArrayList< Location > locations ) {
this
.locations = locations; }
42.
43.
public
String toString()
44.
{
45.
String string =
this
.name +
", "
+
this
.stars +
" stars "
+
"["
+
this
.id +
"]\n"
;
46.
47.
for
( Location location :
this
.locations )
48.
string +=
" "
+ location.toString() +
"\n"
;
49.
50.
return
string;
51.
}
52.
}
01.
package
experiment.morphia;
02.
03.
import
java.util.List;
04.
05.
import
util.Implementor;
06.
07.
import
com.google.code.morphia.Datastore;
08.
import
com.google.code.morphia.dao.BasicDAO;
09.
10.
/**
11.
* Do database stuff here...
12.
*/
13.
@Implementor
( HotelDao.
class
)
14.
public
class
HotelDao
extends
BasicDAO< Hotel, String >
15.
{
16.
/* The Datastore is a wrapper around the MongoDB Java driver and is used to manage
17.
* entities in MongoDB.
18.
*/
19.
Datastore datastore;
// inject this manually for now...
20.
21.
public
HotelDao()
22.
{
23.
super
( HotelTest.getMongo(), HotelTest.getMorphia(),
"hotels"
);
24.
this
.datastore = HotelTest.getDatastore();
25.
}
26.
27.
public
Hotel create( Hotel hotel )
28.
{
29.
this
.datastore.save( hotel );
30.
return
hotel;
31.
}
32.
33.
public
List< Hotel > read()
34.
{
35.
return
this
.datastore.find( Hotel.
class
).asList();
36.
}
37.
38.
public
List< Hotel > read( String query, String value )
39.
{
40.
if
( query ==
null
&& value ==
null
)
41.
return
this
.datastore.find( Hotel.
class
).asList();
42.
43.
return
this
.datastore.find( Hotel.
class
, query, value ).asList();
44.
}
45.
46.
public
List< Hotel > read( String query, Integer value )
47.
{
48.
if
( query ==
null
&& value ==
null
)
49.
return
this
.datastore.find( Hotel.
class
).asList();
50.
51.
return
this
.datastore.find( Hotel.
class
, query, value ).asList();
52.
}
53.
54.
public
void
update( Hotel hotel )
55.
{
56.
this
.datastore.merge( hotel );
57.
}
58.
59.
public
void
remove( Hotel hotel )
60.
{
61.
this
.datastore.delete( hotel );
62.
}
63.
}
01.
package
experiment.morphia;
02.
03.
import
java.util.List;
04.
05.
import
util.Implementor;
06.
import
util.ServiceLocator;
07.
08.
/**
09.
* Do business logic here...
10.
*/
11.
@Implementor
( HotelManager.
class
)
12.
public
class
HotelManager
13.
{
14.
private
HotelDao hotelDao = ServiceLocator.get( HotelDao.
class
);
15.
16.
public
Hotel create( Hotel hotel )
17.
{
18.
return
hotelDao.create( hotel );
19.
}
20.
21.
public
List< Hotel > read()
22.
{
23.
return
hotelDao.read();
24.
}
25.
26.
public
List< Hotel > read( String query, String value )
27.
{
28.
return
hotelDao.read( query, value );
29.
}
30.
31.
public
List< Hotel > read( String query, Integer value )
32.
{
33.
return
hotelDao.read( query, value );
34.
}
35.
36.
public
void
update( Hotel hotel )
37.
{
38.
hotelDao.update( hotel );
39.
}
40.
41.
public
void
delete( Hotel hotel )
42.
{
43.
hotelDao.remove( hotel );
44.
}
45.
}
01.
package
experiment.morphia;
02.
03.
import
java.util.List;
04.
05.
import
util.ServiceLocator;
06.
07.
/**
08.
* Do web service here (except that this isn't a web service, but a squirrel cage)...
09.
*/
10.
public
class
HotelService
11.
{
12.
private
HotelManager hotelManager = ServiceLocator.get( HotelManager.
class
);
13.
14.
public
Hotel create( Hotel hotel )
15.
{
16.
return
this
.hotelManager.create( hotel );
17.
}
18.
19.
public
List< Hotel > read()
20.
{
21.
return
this
.hotelManager.read();
22.
}
23.
24.
public
List< Hotel > read( String query, String value )
25.
{
26.
return
this
.hotelManager.read( query, value );
27.
}
28.
29.
public
List< Hotel > read( String query, Integer value )
30.
{
31.
return
this
.hotelManager.read( query, value );
32.
}
33.
34.
public
void
update( Hotel hotel )
35.
{
36.
this
.hotelManager.update( hotel );
37.
}
38.
39.
public
void
delete( Hotel hotel )
40.
{
41.
this
.hotelManager.delete( hotel );
42.
}
43.
}
001.
package
experiment.morphia;
002.
003.
import
java.net.UnknownHostException;
004.
import
java.util.ArrayList;
005.
import
java.util.List;
006.
import
java.util.Random;
007.
008.
import
org.apache.log4j.Logger;
009.
010.
import
util.ServiceLocator;
011.
012.
import
com.google.code.morphia.Datastore;
013.
import
com.google.code.morphia.Morphia;
014.
import
com.mongodb.BasicDBObject;
015.
import
com.mongodb.DB;
016.
import
com.mongodb.DBCollection;
017.
import
com.mongodb.Mongo;
018.
import
com.mongodb.MongoException;
019.
020.
@SuppressWarnings
(
"unused"
)
021.
public
class
HotelTest
022.
{
023.
public
static
Logger log = Logger.getLogger( HotelTest.
class
);
024.
025.
private
static
Mongo mongodb;
026.
private
static
DB database;
027.
private
static
Morphia morphia;
028.
private
static
Datastore datastore;
029.
030.
private
static
final
String DATABASE_NAME =
"hotels"
;
031.
private
static
final
String HOTEL_NAME =
"Hotel Hyatt"
;
032.
private
static
final
String COLLECTION_NAME = Hotel.
class
.getSimpleName();
033.
034.
public
static
Mongo getMongo() {
return
mongodb; }
035.
public
static
Morphia getMorphia() {
return
morphia; }
036.
public
static
Datastore getDatastore() {
return
datastore; }
037.
038.
/**
039.
* Initialize MongoDB and Morphia for our purposes.
040.
*/
041.
private
static
void
initializeMongoAndMorphia()
042.
{
043.
try
044.
{
045.
mongodb =
new
Mongo(
"localhost"
,
27017
);
046.
}
047.
catch
( UnknownHostException e )
048.
{
049.
log.error(
"MongoDB host not found"
);
050.
}
051.
catch
( MongoException e )
052.
{
053.
log.error(
"Error attempting MongoDB connection for hotels"
, e );
054.
}
055.
056.
database = mongodb.getDB( DATABASE_NAME );
057.
morphia =
new
Morphia();
058.
datastore = morphia.createDatastore( mongodb, DATABASE_NAME );
059.
060.
database.dropDatabase();
// drop any fodder left in from last time...
061.
morphia.map( Hotel.
class
).map( Location.
class
);
062.
}
063.
064.
/**
065.
* Clean up the document we put in here last time (works assuming the hotel name hasn't
066.
* changed) so that we start fresh.
067.
*
068.
* @param key field name ("name").
069.
* @param value hotel name.
070.
*/
071.
private
static
void
deleteDocumentFromCollection( String key, String value )
072.
{
073.
DBCollection collection = database.getCollection( COLLECTION_NAME );
074.
075.
try
076.
{
077.
BasicDBObject dbo =
new
BasicDBObject();
078.
079.
dbo.append( key, value );
080.
collection.remove( dbo );
081.
}
082.
catch
( MongoException e )
083.
{
084.
log.debug(
"Ignored: "
+ e.getMessage() );
085.
}
086.
}
087.
088.
public
static
void
main( String[] args )
089.
{
090.
initializeMongoAndMorphia();
091.
092.
HotelService service =
new
HotelService();
093.
094.
// CREATE
095.
096.
/* Create a random number of hotel chains and put them into the database.
097.
*/
098.
Long milliseconds = System.currentTimeMillis();
099.
Random generator =
new
Random( milliseconds );
100.
int
hotelsCount = HotelFodder.getHotelCount();
101.
102.
// always ensure we've got at least one hotel chain...
103.
int
which = generator.nextInt( hotelsCount );
104.
105.
if
( which ==
0
)
106.
which =
1
;
107.
108.
if
( which ==
1
)
109.
System.out.println(
"Creating a hotel chain..."
);
110.
else
111.
System.out.println(
"Creating "
+ which +
" hotel chains..."
);
112.
113.
while
( which >
0
)
114.
{
115.
Hotel h = service.create( HotelFodder.newHotel() );
116.
which--;
117.
}
118.
119.
/* If I move the stars to the individual locations, I query this way:
120.
* > db.Hotel.find( { "locations" : { $elemMatch : { "stars" : { $gt : 2 } } } } ).count();
121.
* However, this still gives me back the whole Hotel document including the lesser-star
122.
* hotel locations.
123.
*
124.
* This came up as I was assigning stars to locations instead of hotel chains. I stopped
125.
* short of extending this change to what's going on here since it's isn't relevant and I
126.
* don't want to continue to play with it.
127.
*/
128.
129.
// READ
130.
List< Hotel > fourStarChains = service.read(
"stars >"
,
2
);
131.
132.
System.out.println(
"Looking for 3-star or better hotels..."
);
133.
134.
Hotel h_c =
null
;
135.
136.
int
count =
0
;
137.
138.
for
( Hotel hc : fourStarChains )
139.
{
140.
System.out.println( hc );
141.
count++;
142.
}
143.
144.
if
( count ==
0
)
145.
System.out.println(
"(There were no 3-star or better hotels.)"
);
146.
}
147.
}
01.
package
experiment.morphia;
02.
03.
public
class
HotelTuple
04.
{
05.
String hotelName;
06.
Integer stars;
07.
08.
public
HotelTuple( String name, Integer stars )
09.
{
10.
this
.hotelName = name;
11.
this
.stars = stars;
12.
}
13.
}
001.
package
experiment.morphia;
002.
003.
import
java.util.ArrayList;
004.
import
java.util.Random;
005.
006.
public
class
HotelFodder
007.
{
008.
private
static
boolean
once =
false
;
009.
private
static
Random generator1;
010.
private
static
Random generator2;
011.
private
static
Random generator3;
012.
private
static
ArrayList< Location > locations;
013.
private
static
ArrayList< HotelTuple > hotelNamesAndStars;
014.
015.
private
static
void
initializeAddresses()
016.
{
017.
locations =
new
ArrayList< Location >();
018.
019.
locations.add(
new
Location(
2
,
"3222 South 525 West"
,
"Bountiful"
,
"UT"
,
"84101"
,
"US"
) );
020.
locations.add(
new
Location(
2
,
"59, rue Albert Premier"
,
"Bezons"
,
null
,
"95057"
,
"FR"
) );
021.
locations.add(
new
Location(
4
,
"Miquelallee Straß, 23"
,
"Frankfurt"
,
null
,
"65936"
,
"DE"
) );
022.
locations.add(
new
Location(
1
,
"1313 Mockingbird Lane"
,
"Mockingbird Heights"
,
"CA"
,
"06660"
,
"US"
) );
023.
locations.add(
new
Location(
5
,
"12345 Bedford Drive"
,
"Beverly Hills"
,
"CA"
,
"90210"
,
"US"
) );
024.
locations.add(
new
Location(
4
,
"1778 Oregon Avenue"
,
"Provo"
,
"UT"
,
"84606"
,
"US"
) );
025.
locations.add(
new
Location(
4
,
"23, rue du Puits"
,
"Pagny-la-Blanche-Côte"
,
null
,
"55010"
,
"FR"
) );
026.
locations.add(
new
Location(
4
,
"48 Cicada Drive"
,
"Boise"
,
"ID"
,
"83702"
,
"US"
) );
027.
locations.add(
new
Location(
5
,
"5, Boulevard des Capucines"
,
"Paris"
,
null
,
"75008"
,
"FR"
) );
028.
}
029.
030.
private
static
void
initializeHotelNamesAndStars()
031.
{
032.
hotelNamesAndStars =
new
ArrayList< HotelTuple >();
033.
034.
hotelNamesAndStars.add(
new
HotelTuple(
"Hyatt Hotel"
, generator3.nextInt(
5
) +
1
) );
035.
hotelNamesAndStars.add(
new
HotelTuple(
"Bayside Arms"
, generator3.nextInt(
5
) +
1
) );
036.
hotelNamesAndStars.add(
new
HotelTuple(
"Hotel California"
, generator3.nextInt(
5
) +
1
) );
037.
hotelNamesAndStars.add(
new
HotelTuple(
"Bates Motel"
,
0
) );
038.
hotelNamesAndStars.add(
new
HotelTuple(
"Purple Hives"
, generator3.nextInt(
5
) +
1
) );
039.
hotelNamesAndStars.add(
new
HotelTuple(
"Sofitel"
, generator3.nextInt(
5
) +
1
) );
040.
hotelNamesAndStars.add(
new
HotelTuple(
"Novotel"
, generator3.nextInt(
5
) +
1
) );
041.
hotelNamesAndStars.add(
new
HotelTuple(
"Marriott Courtyard"
, generator3.nextInt(
5
) +
1
) );
042.
hotelNamesAndStars.add(
new
HotelTuple(
"Holiday Inn"
, generator3.nextInt(
5
) +
1
) );
043.
hotelNamesAndStars.add(
new
HotelTuple(
"Embassey Suites"
, generator3.nextInt(
5
) +
1
) );
044.
}
045.
046.
public
static
void
initializeFodder()
047.
{
048.
Long milliseconds = System.currentTimeMillis();
049.
050.
if
( once )
051.
return
;
052.
053.
generator1 =
new
Random( milliseconds );
054.
generator2 =
new
Random( milliseconds +
89
);
055.
generator3 =
new
Random( milliseconds +
76
);
056.
057.
initializeAddresses();
058.
initializeHotelNamesAndStars();
059.
once =
true
;
060.
}
061.
062.
public
static
int
getLocationCount()
063.
{
064.
initializeFodder();
065.
066.
return
locations.size();
067.
}
068.
069.
public
static
int
getHotelCount()
070.
{
071.
initializeFodder();
072.
073.
return
hotelNamesAndStars.size();
074.
}
075.
076.
/**
077.
* Generate a new hotel chain with a random name, stars and set of locations.
078.
*
079.
* @return one new Hotel chain.
080.
*/
081.
public
static
Hotel newHotel()
082.
{
083.
initializeFodder();
084.
085.
int
locationCount = getLocationCount();
086.
int
hotelCount = getHotelCount();
087.
088.
HotelTuple tuple = hotelNamesAndStars.get( generator1.nextInt( hotelCount ) );
089.
Hotel hotel =
new
Hotel( tuple.hotelName, tuple.stars );
090.
091.
ArrayList< Location > as =
new
ArrayList< Location >();
092.
093.
// always ensure we've got at least one location in a hotel chain...
094.
int
howMany = generator2.nextInt( locationCount );
095.
096.
if
( howMany ==
0
)
097.
howMany =
1
;
098.
099.
int
next = generator3.nextInt( locationCount );
100.
101.
while
( howMany >
0
)
102.
{
103.
if
( next <
0
)
104.
next = locationCount -
1
;
105.
106.
Location location = locations.get( next );
107.
as.add( location );
108.
howMany--;
109.
next--;
110.
}
111.
112.
hotel.setLocations( as );
113.
114.
return
hotel;
115.
}
116.
117.
public
static
void
main( String[] args )
118.
{
119.
Hotel hotel = newHotel();
120.
System.out.println( hotel.toString() );
121.
}
122.
}