Revision: 1868
Author:
jl...@antwerkz.com
Date: Mon Jul 22 09:35:40 2013
Log: update wiki pages to point to the new locations
http://code.google.com/p/morphia/source/detail?r=1868
Modified:
/wiki/AllAnnotations.wiki
/wiki/DAOSupport.wiki
/wiki/Datastore.wiki
/wiki/Dependencies.wiki
/wiki/EmbeddedAnnotation.wiki
/wiki/EntityAnnotation.wiki
/wiki/FrequentlyAskedQuestions.wiki
/wiki/FrontPage.wiki
/wiki/GettingStarted.wiki
/wiki/GoogleWebToolkit.wiki
/wiki/JRebel.wiki
/wiki/LifecycleMethods.wiki
/wiki/MappingObjects.wiki
/wiki/MongoNewsletterArticleDec2010.wiki
/wiki/MorphiaInUse.wiki
/wiki/Motivation.wiki
/wiki/PropertyAnnotation.wiki
/wiki/Query.wiki
/wiki/QuickStart.wiki
/wiki/ReferenceAnnotation.wiki
/wiki/ReleaseNotes.wiki
/wiki/ReleaseProcess.wiki
/wiki/SLF4JExtension.wiki
/wiki/SoftwareUsed.wiki
/wiki/TableOfContents.wiki
/wiki/Updating.wiki
/wiki/UsingCollections.wiki
/wiki/UsingInterfaces.wiki
/wiki/UsingMorphia.wiki
/wiki/ValidationExtension.wiki
=======================================
--- /wiki/AllAnnotations.wiki Fri Jun 15 01:56:26 2012
+++ /wiki/AllAnnotations.wiki Mon Jul 22 09:35:40 2013
@@ -1,126 +1,1 @@
-#summary All the supported annotations
-#labels Featured
-<wiki:toc>
-
-= Annotations =
-
-Below is a list of all the annotations and a brief descriptions of how to
use them.
-
-Note: In java the default attribute for an annotations can be used without
a name. The name of the default attribute is always *value*. Any time you
see {{{@MyAnnotation("arg")}}} it can be re-written as
{{{@MyAnnotation(valeu = "arg")}}}, and must be if you add additional
attributes.
-
-== Entity ==
-Marks entities to be stored directly in a collection. Look
[EntityAnnotation here] for more examples.
-
-This annotations is optional in most cases. There is no harm in including
it to be more verbose, and make clear the intention for the class.
-
-=== Collection Name ==
-Attribute name: *value*
-
-{{{@Entity("name")}}}
-
-=== Capped ===
-Attribute name: *cap*
-
-{{{@Entity(cap = @CappedAt(...))}}}
-
-=== Do not store classname ===
-Attribute name: *noClassnameStored*
-
-{{{@Entity(noClassnameStored = true)}}}
-
-This attribute is temporary until polymorphism is completed.
-
-== Indexes ==
-
-In addition to being able to declare an index on a single field you can
also declare the indexes at the class level. This allows you to create more
than just a single field index; it allows you to create compound indexes
with multiple fields.
-
-=== Compound Indexes ===
-Compound indexes are indexes that include several fields, in a specific
order. They are annotated on the the class itself since they include
multiple fields. As an example imagine you have a collection that stores
changes made by a user. If you want to be able to quickly query recent
changes for a given user, you would want to create an index containing both
user and date; the order of the fields is significant so please read up on
the mongo side of things for optimal performance.
-
-{{{
-@Entity // this is require to know where the indexes are to be created
-@Indexes( @Index("user, -date") )
-public class ChangeLog{
- Date date;
- String user;
- Record changedRecord;
-}
-
-}}}
-
-The minus on "-date" indicates that the field is indexed in descending
order making it quicker to sort from most recent to oldest. This is the
same syntax used when sorting or ordering results from a query.
-
-Say you decided you also needed to be able to quickly find recent changes
for the record being changed. You could change the annotation to:
-{{{
-@Indexes({
- @Index("user, -cs"),
- @Index("changedRecord, -cs")})
-}}}
-
-And now you will have two compound indexes on that collection.
-
-If you like you can also define single field indexes in this fashion as
well; it is recommended that you don't since it is more error prone.
-
-
-== Id ==
-Marks a field in an {{{@Entity}}} to be the "_id" field in mongodb.
-
-{{{
-@Entity
-class Myclass {
- @Id ObjectId id = new ObjectId();
- ...
-}
-}}}
-
-== Property ==
-See [PropertyAnnotation]
-
-== Transient ==
-The field with not be persisted.
-
-== Serialized ==
-The field with be converted to binary, and persisted.
-
-== {{{NotSaved}}} ==
-The field will not be saved, but can be loaded. Good for data migration.
-
-== {{{AlsoLoad}}} ==
-The field will can be loaded as any of the supplied names. Good for data
migration.
-
-== Indexed ==
-The field will be indexed. See [Datastore the datastore docs].
-
-== Version ==
-Marks a field in an {{{@Entity}}} to control optimistic locking for that
entity. If the versions change while modifying an entity a
ConcurrentModificationException will be throw in the write method
(save/delete/etc). This field will be automatically managed for you --
there is no need to set a value and you should not do so anyway.
-
-{{{
-@Entity
-class Myclass {
- ...
- @Version Long v;
-}
-}}}
-
-== Reference ==
-Marks fields as stored in another collection and which are linked (by a
dbref reference field). When the Entity is loaded, so is the (direct)
reference.
-
-Attribute name: *lazy*
-
-Instead of loading the referenced field with the Entity, it will be lazily
loaded on the first method call of the proxy instance.
-
-Attribute name: *ignoreMissing*
-
-When loading bad references won't generate an exception
-
-Attribute name: *concreteClass*
-
-The class type to create for these references
-
-Look [ReferenceAnnotation here] for more examples.
-
-== Embedded ==
-Allows customization of certain options. Look [EmbeddedAnnotation here]
for more examples.
-
-== Lifecycle Annotations ==
-See the this [LifecycleMethods page].
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/AllAnnotations here]
=======================================
--- /wiki/DAOSupport.wiki Sat Dec 31 07:40:51 2011
+++ /wiki/DAOSupport.wiki Mon Jul 22 09:35:40 2013
@@ -1,70 +1,1 @@
-#summary Describes the Morphia DAO support classes.
-
-= Using Data Access Objects (DAO) =
-
-It is considered good practice to abstract the underlying persistence
strategy away from the calling code, by encapsulating the persistence calls
within Data Access Objects (DAOs). That means that your controller (or
action) classes can have a DAO object injected, and use it, without having
to worry how the data is persisted, or retrieved.
-
-Morphia supports this style by providing an abstract BasicDAO
implementation, based on the DAO interface, that uses the Datastore to
persist, and query for java POJOs. This abstract class implements all the
basic DAO methods you would want to use to create/update, read, and delete
objects. It is provided as an example and pattern that you can use.
-
-This means that by having your DAO class extend the BasicDAO class, you
would normally only need to implement finder methods to return query
results for you domain objects.
-
-Let's look at how we could use the DAO support to manage blog entries.
First of all, we would need to create a DAO class that extends
BasicDAO<T,V>:
-
-{{{
-
-public class BlogEntryDAO extends BasicDAO<BlogEntry, ObjectId> {
- public BlogEntryDAO( Morphia morphia, Mongo mongo ) {
- super(mongo, morphia, "myBlogDb");
- }
-}
-}}}
-
-Note that DAO uses generics to define a parameter class. This means you
don't have to do any casting when using the DAO methods.
-
-Since all the methods are implemented for us, we only need to do two
important thing:
-
- * Implement a constructor. The constructor passes information on to the
DAO superclass.
- * Implement finder methods
-
-Now, we can use this class to persist and load blog entries:
-{{{
-...
-BlogEntryDAO blogEntryDAO = new BlogEntryDAO(...);
-
-// get one specific blog entry
-ObjectId blogEntryId = ...;
-BlogEntry myBlogEntry = blogEntryDAO.get(blogEntryId);
-
-// update it
-myBlogEntry.setTitle("My Blog Entry");
-blogEntryDAO.save(myBlogEntry);
-
-// or just delete it
-blogEntryDAO.deleteById(myBlogEntry.getId());
-...
-}}}
-
-In a web application environment, we would probably use a dependency
injection framework (like Guice or Spring) to inject the dependencies into
the DAO, and then inject the DAO into a controller, so the controller would
never directly deal with the gritty details.
-
-This approach is highly recommended, as it keeps your code tidy and less
prone to errors.
-
-== Custom finder methods ==
-
-Although the abstract DAO implementation has find() methods, we sometimes
need custom finder methods to filter the data, and apply custom sorting.
-
-So, if we wanted to create a finder method that returns all blog entries
where the title starts with a particular String (sorting in alphabetical
order), we could add the following method to the BlogEntryDAO:
-
-{{{
-..
-public List<BlogEntry> findByTitle( String title ) {
- Pattern regExp = Pattern.compile(title + ".*",
Pattern.CASE_INSENSITIVE);
- return ds.find(entityClazz).filter("title",
regExp).sort("title").asList();
-}
-...
-}}}
-
-We perform the query, sorting the results (hopefully using an index), and
then return the result as a list instead of as an iterator.
-
-== Name/Package Changes ==
-
-In older versions of Morphia the dao class was called {{{DAO}}} but in
newer versions there is a {{{DAO}}} interface, and {{{BasicDAO}}}
implementation (to extend) now is their own package, "dao". The old class
still exists for backwards compatibility but is marked as {{{@
Deprecated}}}.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/DAOSupport here]
=======================================
--- /wiki/Datastore.wiki Tue Nov 8 22:57:09 2011
+++ /wiki/Datastore.wiki Mon Jul 22 09:35:40 2013
@@ -1,138 +1,1 @@
-#summary A type-safe set of operations for mongodb
-#labels Featured
-
-<wiki:TOC max_depth=2 />
-
-= Datastore =
-The {{{Datastore}}} interface provides type-safe methods for accessing and
storing your java objects in MongoDB. It provides get/find/save/delete
methods for working with your java objects.
-
-== Get Methods ==
-
-Get methods return instance(s) of your entities by its {{{@Id}}}. It is
really just a short-cut for using {{{find(...)}}} with a criteria of id
values. It always returns an entity, or {{{null}}} if none is found.
-
-{{{
-Datastore ds = ...
-
-Hotel hotel = ds.get(Hotel.class, hotelId);
-}}}
-
-== Find Methods ==
-
-The find methods are a lightweight wrapper around using a [Query Query]
(as with createQuery()). As a wrapper it will return a [Query Query], which
also supports {{{Iterable<T>}}} and the {{{QueryResults}}} interface.
-
-{{{
-Datastore ds = ...
-
-//use in a loop
-for(Hotel hotel : ds.find(Hotel.class, "stars >", 3))
- print(hotel);
-
-//get back as a list
-List<Hotel> hotels = ds.find(Hotel.class, "stars >", 3).asList();
-
-//sort the results
-List<Hotel> hotels = ds.find(Hotel.class, "stars >",
3).sort("-stars").asList();
-
-//get the first matching hotel, by querying with a limit(1)
-Hotel gsHotel = ds.find(Hotel.class, "name", "Grand Sierra").get();
-
-//same as
-Hotel gsHotel = ds.find(Hotel.class, "name =", "Grand Sierra").get();
-
-}}}
-
-Here is the list of valid operators:
-["=", "==","!=", "<>", ">", "<", ">=", "<=", "in", "nin", "all", "size", "exists"]
-
-If no operator is used, "=" is assumed, as in the last example above.
-"=" is the same as "==", equal
-"!=" is the same as "<>", not equal
-
-== Save Methods ==
-
-This is where a lot of the work goes on under the covers. The methods are
very straight forward.
-
-{{{
-Datastore ds = ...
-
-Hotel hotel = new Hotel();
-
-ds.save(hotel);
-
-//@Id field is filled in for you (after the save), if you didn't set it.
-ObjectId id = hotel.getId();
-
-}}}
-
-== Delete Methods ==
-
-This is pretty self-explanatory. The methods will delete items based on a
{{{Query}}}, id, or an entity.
-
-{{{
-Datastore ds = ...
-ds.delete(Hotel.class, "Grand Sierra Resort");
-//use a query
-ds.delete(ds.createQuery(Hotel.class).filter("pendingDelete", true));
-}}}
-
-== {{{FindAndDelete}}} ==
-
-One of the underlying features in MongoDB is the ability to do some
operations in an atomic fashion. This can be done by deleting an Entity,
and returning the deleted item at the same time. The {{{FindAndDelete}}}
method will find the first item, and delete it (while returning it).
-
-{{{
-Datastore ds = ...
-Hotel grandSierra = ds.findAndDelete(ds.get(Hotel.class, "Grand Sierra
Resort"));
-}}}
-
-== Update Methods ==
-
-Updates are are applied at the server and allow for complicated but very
efficient (when compared to saving the whole entity again) update
operations.
-
-Say you are tracking the last login for users. Each time a user
successfully enters the site you can update a timestamp, but don't
necessarily want to load and resave the whole user document. You can
instead update the user locally and perform an efficient update of just the
last login.
-
-{{{
-@Entity
-class User
-{
- @Id private ObjectId id;
- private long lastLogin;
- //... other members
-
- private Query<User> queryToFindMe()
- {
- return
datastore.createQuery(User.class).field(Mapper.ID_KEY).equal(id);
- }
-
- public void loggedIn()
- {
- long now = System.currentTimeMillis();
- UpdateOperations<User> ops =
datastore.createUpdateOperations(User.class).set("lastLogin", now);
- ds.update(queryToFindMe(), ops);
- lastLogin = now;
- }
-}
-
-}}}
-
-{{{
-//maybe add example on managing an embedded array of login times
-}}}
-
-Read more on [Updating].
-
-== Ensure Indexes and Caps ==
-
-These methods should be called after you have registered you entities with
Morphia. It will then *synchronously*, by default, create your indexes, and
capped collections. One option is call them each time you start your
application, or via an administrative interface, or during a deployment
script. It might be best to make sure indexes can be built in the
*background* if there is *already data*.
-
-If you delay index building to later in the application life-cycle you
should *make sure to create the capped collections (ensureCaps) at
startup*, before any data is persisted.
-
-*Note:* Doing this on an existing system, with existing indexes and capped
collections, should take no time (and do nothing). If the collection isn't
capped, or has different setting you will get an error in the logs, but
nothing will be done to the existing collections.
-
-{{{
-Morphia m = ...
-Datastore ds = ...
-
-m.map(MyEntity.class);
-ds.ensureIndexes(); //creates all defined with @Indexed
-ds.ensureCaps(); //creates all collections for @Entity(cap=@CappedAt(...))
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/Datastore here]
=======================================
--- /wiki/Dependencies.wiki Sun Oct 31 08:51:08 2010
+++ /wiki/Dependencies.wiki Mon Jul 22 09:35:40 2013
@@ -1,53 +1,1 @@
-#summary List of runtime JAR dependencies for Morphia.
-<wiki:toc>
-
-= Dependencies =
-
-Morphia depends on the following third party JARs:
- * The [
http://github.com/mongodb/mongo-java-driver/downloads MongoDB
java driver] (see the required version for each [ReleaseNotes Morphia
Release]
- * [Optional] (but needed if you use Maven)
- * [
http://sourceforge.net/projects/cglib/files/ CGLib]
- * [
http://proxytoys.codehaus.org/download.html ProxyToys]
-
-If you use [
http://maven.apache.org Maven2] to build your project, it will
automatically download all dependencies for you.
-
-
-
-= Including Morphia (in your project) =
-
-== Manually ==
-
-Add the dependencies above to your class-path and compile.
-
-== Through Maven ==
-
- * If you use Maven2 to manage your project, you can reference Morphia as
a dependency.
- * Repo: {{{
http://morphia.googlecode.com/svn/mavenrepo/}}}
- * Project Settings:
- {{{
-<dependency>
- <groupId>com.google.code.morphia</groupId>
- <artifactId>morphia</artifactId>
- <version>###</version>
-</dependency>
-<!-Optional Jars (for certain features) but required by maven for bulding.
-->
-<dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib-nodep</artifactId>
- <version>[2.1_3,)</version>
- <type>jar</type>
- <optional>true</optional>
-</dependency>
-<dependency>
- <groupId>com.thoughtworks.proxytoys</groupId>
- <artifactId>proxytoys</artifactId>
- <version>1.0</version>
- <type>jar</type>
- <optional>true</optional>
-</dependency>
-
-}}}
-
-== From Source ==
-
-You can check out from subversion and build it yourself. You will need
[
http://maven.apache.org Maven2] for this. After you've
[
http://code.google.com/p/morphia/source/checkout checked out] the project,
change into the morphia directory, and run "mvn install" (*Note*: Will need
to have Mongo running locally for the tests to pass).
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/Dependencies here]
=======================================
--- /wiki/EmbeddedAnnotation.wiki Wed Nov 17 09:24:37 2010
+++ /wiki/EmbeddedAnnotation.wiki Mon Jul 22 09:35:40 2013
@@ -1,75 +1,1 @@
-#summary Describes how to annotate fields with embedded objects.
-
-= Embedding Objects =
-
-We're often dealing with an object structure that does not just have a
flat list of fields, but rather a tree of objects. For example, look at the
following classes:
-
-{{{
-public class Hotel {
-
- private String name;
- private int stars;
- private Address address;
-
- // ... getters and setters
-}
-}}}
-
-where the Address class looks like this:
-
-{{{
-public class Address {
-
- private String street;
- private String city;
- private String postCode;
- private String country;
-
- // ... getters and setters
-}
-}}}
-
-As a rule of thumb, you should @Embedded for objects that are dependent on
the parent object (and therefore have no life outside it), and are not
shared between objects. If you need to reference another collection object,
look at {{{@Reference}}}, or storing a {{{Key}}} instead.
-
-We just annotate the above classes with @Property and @Embedded:
-
-{{{
-@Entity
-public class Hotel {
-
- @Id
- private String id;
-
- private String name;
- private int stars;
-
- @Embedded
- private Address address;
-
- // ... getters and setters
-}
-
-...
-
-import com.google.code.morphia.annotations.Embedded;
-
-@Embedded
-public class Address {
-
- private String street;
- private String city;
- private String postCode;
- private String country;
-
- // ... getters and setters
-}
-}}}
-
-As you can see here, _classes used solely as embedded objects should not
use @Id_.
-
-By default, Morphia uses the field name as the value name in Mongo. This
can be overridden by specifying a name on the @Embedded annotation:
-
-{{{
- @Embedded("blog_comments")
- private List<Comment> comments;
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/EmbeddedAnnotation here]
=======================================
--- /wiki/EntityAnnotation.wiki Sat Aug 14 11:55:53 2010
+++ /wiki/EntityAnnotation.wiki Mon Jul 22 09:35:40 2013
@@ -1,154 +1,1 @@
-#summary Define your Entity
-
-= Entity Annotation =
-
-If you want to store your class instance in Mongo via Morphia, the first
thing you need to do is annotate your class as an @Entity:
-
-{{{
-import com.google.code.morphia.annotations.Entity;
-
-@Entity
-public class Hotel {
-...
-}
-}}}
-
-== Name + Constructor ==
-You can also optionally set a name for your MongoDB {{{DBCollection}}}
name.
-You will also need a (no-args) default constructor.
-
-{{{
-@Entity("hotels")
-public class Hotel {
-...
- public Hotel() {
- }
-...
-}
-}}}
-
-Note that your default constructor does not need to be public, it can also
be protected or private.
-
-== Class name in document and how to suppress it ==
-
-The @Entity annotation provides another optional parameter to not store
the class name in the document.
-
-{{{
-@Entity(value="hotels", noClassnameStored=true)
-public class Hotel {
-...
- public Hotel() {
- }
-...
-}
-}}}
-
-The default behavior is to store the class name in the document.
-
-*Why would you need it?* This is mainly used when storing different
entities in the same collection and reading them back as the base or super
class.
-
-Ex.
-{{{
-@Entity("animals") abstract class Animal { String name; }
-@Entity("animals") Cat extends Animal { ... }
-@Entity("animals") Dog extends Animal { ... }
-
-//And then performing the following query...
-List<Animal> animals = ds.createQuery(Animal.class).asList();
-}}}
-
-As you can see, without the class name stored in the document, Morphia
wouldn't know which class to actually create.
-
-If you are only storing a single entity type in the collection and you are
concerned about datasize, it would be safe to add the
noClassnameStored=true parameter to the Entity annotation.
-
-
-== @Id ==
-Classes annotated with {{{@Entity}}} require unique {{{@Id}}} values;
these values are stored in the MongoDB "_id" field, which has a unique
index requirement. The Hotel class above would have:
-
-
-{{{
-@Entity
-public class Hotel {
-
- @Id
- private ObjectId id;
-...
-}
-}}}
-
-Mongo will generate the Id for your new objects, so you don't need to
worry about that. It will be stored as an {{{ObjectId}}}; If you use any
other type than ObjectId you must set the value yourself.
-
-== @Indexed ==
-
-This annotation applies an index to a field. The indexes are applied when
the datastore.ensureIndexes() method is called... more on this below.
-
-You apply the Indexed annotation on the field you want indexed by MongoDB.
-
-{{{
-@Entity
-public class Product {
-
- @Id
- private ObjectId id;
-
- @Indexed(value=IndexDirection.ASC, name="upc", unique=true,
dropDups=true)
- private String upcSymbol;
-...
-}
-}}}
-
-The parameters are:
-
-*value:* Indicates the direction of the index; IndexDirection.ASC
-(ascending), IndexDirection.DESC (descending), IndexDirection.BOTH
-(both), default is ascending
-
-*name:* The name of the index to create; default is to let the mongodb
-create a name (in the form of key1_1/-1_key2_1/-1...
-
-*unique:* Creates the index as a unique value index; inserting
-duplicates values in this field will cause errors, default false
-
-*dropDups:* Tells the unique index to drop duplicates silently when
-creating; only the first will be kept. default false
-
-*Datastore.ensureIndexes()* needs to be called to apply the indexes to
MongoDB. The method should be called after you have registered your
entities with Morphia. It will then synchronously create your indexes. This
should probably be done each time you start your application.
-
-Note: Doing this on an existing system, with existing indexes and capped
collections, should take no time (and do nothing).
-
-{{{
-Morphia m = ...
-Datastore ds = ...
-
-m.map(Product.class);
-ds.ensureIndexes(); //creates all defined with @Indexed
-}}}
-
-You can read more about MongoDB indexes here,
http://www.mongodb.org/display/DOCS/Indexes
-
-== Embedded ==
-
-You can also choose to create a class that will be embedded in the Entity,
we use the {{{@Embedded}}} annotation in this case. For example, the
{{{Hotel}}} class above might have an {{{Address}}}. The Address would be
an inseparable part of the {{{Hotel}}}, would not have its own ID, and
would not be stored in a separate {{{collection}}}. In this case we would
annotate the Address class as {{{@Embedded}}}:
-
-{{{
-
-@Entity
-public class Hotel {
- ...
- @Id
- private ObjectId id;
-
- @Embedded
- private Address address;
- ...
-}
-
-...
-
-@Embedded
-public class Address {
- ...
-}
-}}}
-
-As you can see, classes with @Embedded annotation do not need an
{{{@Id}}}. This is because they always be included in another class. In
fact, they are not allowed to have an {{{@Id}}} if the class is annotated
with {{{@Embedded}}}.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/EntityAnnotation here]
=======================================
--- /wiki/FrequentlyAskedQuestions.wiki Mon Dec 6 16:01:07 2010
+++ /wiki/FrequentlyAskedQuestions.wiki Mon Jul 22 09:35:40 2013
@@ -1,90 +1,1 @@
-#summary Frequently Asked Questions
-#labels Featured
-
-<wiki:toc max_depth="2" />
-
-= Frequently Asked Questions =
-
-== Why do I need to change my {{{@Id}}} field from {{{String}}} to
{{{ObjectId}}} ==
-If you wanted an *automatically generated id* (the default {{{_id}}} value
for mongodb) in versions prior to 0.95 you could do this:
-{{{
-@Id String id;
-}}}
-
-Or make queries using a string version of your {{{ObjectId}}} value
because we automatically tried to convert any string into an {{{ObjectId}}}
for you.
-
-After version 0.95 this is no longer the case. You now should change that
definition above from {{{String}}} to {{{ObjectId}}} like this:
-{{{
-@Id ObjectId id;
-}}}
-
-There are many reasons to do this. Always trying to convert from
string->objectid was confusing (in documentation), and ambiguous in certain
cases and made it impossible to use a string value between 18-24 characters
long with alpha-numeric values (a hex string). It also was confusing
because you had to remember that in other languages and the shell you had
to use an {{{ObjectId}}}.
-
-To simplify things and make it more transparent we have remove this
implicit conversion.
-
-If you don't want to use an {{{ObjectId}}} type you can manage your
{{{@Id}}} value yourself. There is a sample class that uses an
auto-incrementing {{{long}}} (stored as a counter on the server) as an
example. Natural keys are great things to use as your id values (immutable
values like a username, or email are an example in some applications).
-
-== Do you have to close connections? ==
-
-Not really. The Mongo driver keeps a connection pool per Mongo instance.
If you wish to release those resources, just make sure you stop using the
Mongo instance.
-
-== How can I use data that is already in MongoDB (like from another
framework/mapper)? ==
-
-If you are starting with data and you want to make sure you build your
java {{{POJO}}} in a way you can load the data below are a few tips.
-
- # {{{@AlsoLoad("old_name")}}} (if you don't want to save the old format)
-{{{
-{
-_id:1,
-desc:null,
-created_at:ISODate("2010-12-06T23:52:50.258Z"),
-updated_at:ISODate("2010-12-06T24:51:34.132Z")
-}
-}}}
-{{{
-class MyEntity {
- @Id long id;
-
- String desc;
-
- @AlsoLoad("thumbnail_filename")
- String thumbnail;
-
- @AlsoLoad("created_at")
- Date dateCreated = new Date();
-
- @AlsoLoad("updated_at")
- Date dateUpdated;
-}
-}}}
- # {{{@Property("old_name")/@Embedded("old_name")}}}
-{{{
-class MyEntity {
- @Id long id;
-
- String desc;
-
- @Property("thumbnail_filename")
- String thumbnail;
-
- @Property("created_at")
- Date dateCreated = new Date();
-
- @Property("updated_at")
- Date dateUpdated;
-}
-}}}
-
-== Should I use a capped collection for referenced/linked entities? ==
-
-You can but a reference is made up of the collection name + the {{{_id}}}
field value. In capped collections the {{{_id}}} field is not unique and
references might be ambiguous.
-
-== Huh, why is there a className field in my Document? Can I remove it? ==
-
-Yes, you can; look
[EntityAnnotation#Class_name_in_document_and_how_to_suppress_it here]
-
-Please be careful that you follow the ClassPerCollection pattern if you
remove the className from your persisted entites.
-
-==Question about life cycle methods==
-Absolutely:
- * See the [LifecycleMethods Lifecycle Annotations]
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/FrequentlyAskedQuestions here]
=======================================
--- /wiki/FrontPage.wiki Mon Jun 24 08:02:23 2013
+++ /wiki/FrontPage.wiki Mon Jul 22 09:35:40 2013
@@ -1,67 +1,1 @@
-=NOTICE=
-This project has been migrated to [
https://github.com/mongodb/morphia
github]. All the source code and issues have been migrated to the new
site. Development will continue there. Mailing lists and discussion will
remain here.
- ----
-*Morphia* is a lightweight type-safe library for mapping Java objects
to/from [
http://mongodb.org MongoDB]:
-<wiki:gadget
url="
http://www.ohloh.net/p/morphia/widgets/project_partner_badge.xml"
height="55" border="0" />
- * Easy to use, and very *lightweight*; reflection is used once per type
and cached for *good performance*.
- * [Datastore] and [DAOSupport DAO]<T,V> access abstractions, or roll your
own...
- * *Type-safe*, and *Fluent [Query]* support with (runtime) validation
- * *Annotations* based mapping behavior; there are no XML files.
- * *Extensions*: [ValidationExtension Validation (jsr303)], and
[SLF4JExtension SLF4J Logging]
-
-{{{
-@Entity("employees")
-class Employee {
- @Id ObjectId id; // auto-generated, if not set (see ObjectId)
- String firstName, lastName; // value types are automatically persisted
- Long salary = null; // only non-null values are stored
-
- Address address; // by default fields are @Embedded
-
- Key<Employee> manager; //references can be saved without automatic
loading
- @Reference List<Employee> underlings = new ArrayList<Employee>(); //refs
are stored*, and loaded automatically
-
- @Serialized EncryptedReviews; // stored in one binary field
-
- @Property("started") Date startDate; //fields can be renamed
- @Property("left") Date endDate;
-
- @Indexed boolean active = false; //fields can be indexed for better
performance
- @NotSaved string readButNotStored; //fields can loaded, but not saved
- @Transient int notStored; //fields can be ignored (no load/save)
- transient boolean stored = true; //not @Transient, will be ignored by
Serialization/GWT for example.
-
- //Lifecycle methods -- Pre/PostLoad, Pre/PostPersist...
- @PostLoad void postLoad(DBObject dbObj) { ... }
-}
-
-...
-
-Datastore ds = ...; // like new Morphia(new Mongo()).createDatastore("hr")
-morphia.map(Employee.class);
-
-ds.save(new Employee("Mister", "GOD", null, 0));
-
-Employee boss =
ds.find(Employee.class).field("manager").equal(null).get(); // get an
employee without a manager
-
-Key<Employee> scottsKey = ds.save(new Employee("Scott", "Hernandez",
ds.getKey(boss), 150*1000));
-
-//add Scott as an employee of his manager
-UpdateResults<Employee> res = ds.update(boss,
ds.createUpdateOperations(Employee.class).add("underlings", scottsKey));
-
-Employee scottsBoss = ds.find(Employee.class).filter("underlings",
scottsKey).get(); // get Scott's boss; the same as the one above.
-
-for (Employee e : ds.find(Employee.class, "manager", boss))
- print(e);
-
-}}}
- * [LifecycleMethods Lifecycle Method/Event] Support
- * Works great with Guice, Spring, and other DI frameworks.
- * Many extension points (new annotations, converters, mapping behavior,
logging, etc.)
- * Does not store Null/Empty values (by default).
- * GWT support (entities are just POJOs) -- (GWT ignores annotations)
- * Advanced mapper which allows raw conversion, {{{void
toObject(DBObject)}}} or {{{ DBObject fromObject(Object)}}}
-
-Please continue by reading the QuickStart or looking at a list of
AllAnnotation.
-
-*Note*: @Reference will not save objects, just a reference to them; You
must save them yourself.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/FrontPage here]
=======================================
--- /wiki/GettingStarted.wiki Mon Aug 13 20:46:54 2012
+++ /wiki/GettingStarted.wiki Mon Jul 22 09:35:40 2013
@@ -1,51 +1,1 @@
-#summary Things you need to do before you can start using Morphia.
-
-= Getting Started =
-
-You will need Java SE 5 or higher. You will also need access to a Mongo
database (
http://mongodb.org). Please take a look at the rest of the
[Dependencies].
-
-This will consist of a few code snippets to get you going!
-
-== First Entity ==
-{{{
-@Entity
-class MyEntity {
- @Id ObjectId id;
- String name;
-}
-}}}
-== Initialize Morphia/Mongo ==
-{{{
-
-Datastore ds = new Morphia().createDatastore("myDB"); //best to use
(Mongo, String) method, where Mongo is a singleton.
-
-...
-
-//at application start
-//map classes before calling with morphia map* methods
-ds.ensureIndexes(); //creates indexes from @Index annotations in your
entities
-ds.ensureCaps(); //creates capped collections from @Entity
-}}}
-
-== Saving ==
-{{{
-
-MyEntity e = ...;
-
-ds.save(e);
-
-}}}
-
-== Querying ==
-
-{{{
-MyEntity e = ds.find(MyEntity.class).get(); //get the first one by type
-MyEntity e =
ds.find(MyEntity.class).field("name").equal("someName").get(); //get the
first one where name = "someName"
-
-}}}
-
-== Datastore ==
-
-The datastore represents a type-safe wrapper against the basic mongodb
operations (find, save, delete). For each operation you can specify the
class type you are working with and parameters to the operation.
-
-see more at the [Datastore] page...
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/GettingStarted here]
=======================================
--- /wiki/GoogleWebToolkit.wiki Mon Mar 21 09:53:46 2011
+++ /wiki/GoogleWebToolkit.wiki Mon Jul 22 09:35:40 2013
@@ -1,10 +1,1 @@
-#summary Using Morphia with GWT
-#labels Extension
-
-= Using Morphia with GWT =
-
-To use morphia with GWT all you need to do is download the gwt module jar
and add this to your {{{.gwt.xml}}} file:
-
-{{{
- <inherits name='com.google.code.morphia.Morphia' />
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/GoogleWebToolkit here]
=======================================
--- /wiki/JRebel.wiki Mon Mar 21 09:53:20 2011
+++ /wiki/JRebel.wiki Mon Jul 22 09:35:40 2013
@@ -1,45 +1,1 @@
-#summary JRebel Extension
-#labels Extension
-
-= Introduction =
-
-This is a simple extension to Morphia to make classes being re-mapped to
morphia, once they are reloaded by JRebel.
-
-== Prerequisits ==
-
-Of course you need to run JRebel (
http://zeroturnaround.com) for this
extension to be useful.
-On top of that, you need to tell JRebel about the Plugin. In order to do
that, add the following two new Elements to the VM startup command:
-
-{{{
--Drebel.morphia=true
-Drebel.plugins=/path/to/morphia-jrebel-plug-1.0-SNAPSHOT.jar
-}}}
-
-If you´re using Eclipse with the JRebel Plugin this can be skipped and
instead configured in the Agent Settings GUI.
-
- * Choose Window->Prefs->JRebel
- * Click Agent Settings
- * Choose Plugins Tab
- * Click custom plugins
- * add the plugin jar, OK
- * Choose custom, add key "rebel.morphia" with value of "true"
-
-= Using =
-Register the Extension to your Morphia instance
-
-{{{
-new JRebelExtension(morphia);
-}}}
-
-== Dependencies ==
-
-=== Maven ===
- * If you use Maven2 to manage your project, you can reference the
Extension as a dependency.
- * Repo: {{{
http://morphia.googlecode.com/svn/mavenrepo/}}}
- * Project Settings:
-{{{
-<dependency>
- <groupId>com.google.code.morphia</groupId>
- <artifactId>morphia-jrebel-plug</artifactId>
- <version>1.0-SNAPSHOT</version>
-</dependency>
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/JRebel here]
=======================================
--- /wiki/LifecycleMethods.wiki Tue Nov 30 06:29:46 2010
+++ /wiki/LifecycleMethods.wiki Mon Jul 22 09:35:40 2013
@@ -1,53 +1,1 @@
-#summary A list of Annotation to decorate your Entity with for lifecycle
events.
-<wiki:toc>
-
-= Lifecycle Method Annotations =
-
-There are various annotations which can be used to register callbacks on
certain lifecycle events. These include Pre/Post-Persist (Save), and
Pre/Post-Load.
-
- * {{{@PrePersist}}} - Called before save, it can return a DBObject in
place of an empty one.
- * {{{@PostPersist}}} - Called after the save call to the datastore
- * {{{@PreLoad}}} - Called before mapping the datastore object to the
entity (POJO); the DBObject is passed as an argument (you can
add/remove/change values)
- * {{{@PostLoad}}} - Called after mapping to the entity
-
-See the AllAnnotation for a full list of the annotations supported.
-== Examples ==
-
-Here is a one of the test classes:
http://code.google.com/p/morphia/source/browse/trunk/morphia/src/test/java/com/google/code/morphia/TestDatastore.java#82
-
-All parameters and return values are options in your implemented methods.
-
-=== Simple {{{@PrePersist}}} ===
-Here is a simple example of an entity that always saves the Date it was
last updated at.
-{{{
-
-class BankAccount {
- @Id String id;
- Date lastUpdated = new Date();
-
- @PrePersist void prePersist() {lastUpdated = new Date();}
-}
-
-}}}
-
-=== {{{EntityListerners}}} ===
-In addition, you can separate the lifecycle event implementation in an
external class, or many.
-{{{
-
-@EntityListeners(BackAccountWatcher.class)
-class BankAccount {
- @Id String id;
- Date lastUpdated = new Date();
-}
-
-class BankAccountWatcher{
-
- @PrePersist void prePersist(BankAccount act) {act.lastUpdated = new
Date();}
-
-}
-
-}}}
-
-== No Delete Support ==
-
-Because deletes are usually done with queries there is no way to support a
Delete lifecycle event. If, or when, server-side triggers are enabled there
may be some support for this, but even then it will be hard to imagine how
this would logically fit.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/LifecycleMethods here]
=======================================
--- /wiki/MappingObjects.wiki Wed Jun 23 12:13:18 2010
+++ /wiki/MappingObjects.wiki Mon Jul 22 09:35:40 2013
@@ -1,75 +1,1 @@
-#summary Mapping objects to/from MongoDB using Morphia.
-
-= Mapping Objects =
-
-Once we've annotated our objects, most of the hard work is done. Now all
we need to do is create an instance of Morphia, tell it which classes we
want to map, and then we can start mapping between Mongo documents and Java
objects.
-
-== Create a Morphia instance ==
-
-The first thing you need to do is create a Morphia instance, and tell it
which classes you want to map. It is recommended that you create this
instance once, and reuse it.
-
-{{{
-import com.google.code.morphia.Morphia;
-...
-Morphia morphia = new Morphia();
-morphia.map(BlogEntry.class)
- .map(Author.class);
-...
-}}}
-
-Each class that you map will be validated, and a MappingException will be
thrown if the class is not valid for some reason.
-
-You can also tell Morphia to scan a package, and map all classes found in
that package:
-
-{{{
-...
-morphia.mapPackage("my.package.with.only.mongo.entities");
-...
-}}}
-== Advanced Usage ==
-
-It is possible to manually use the morphia instance to map to and from
DBObjects to interact with the java driver directly. Below are some
examples of how to do this.
-
-=== Mapping a Java for Persistence ===
-
-It is possible to manually use the morphia instance to map to and from
DBObjects to interact with the java driver directly. Here is an example of
that.
-
-Let's say we have a blog entry object, and we want to save it to a
collection in a Mongo database. We just call the toDBObject() method on our
morphia instance, passing the Java object. We can then save the resulting
DBObject directly to Mongo.
-
-{{{
-Morphia morphia = ...;
-Mongo mongo = ...;
-DB db = mongo.getDB("BlogSite");
-
-BlogEntry blogEntry = ...; // this is our annotated object
-
-// map the blog entry to a Mongo DBObject
-DBObject blogEntryDbObj = morphia.toDBObject(blogEntry);
-
-// and then save that DBObject in a Mongo collection
-db.getCollection("BlogEntries").save(blogEntryDbObj);
-}}}
-
-Our blog entry object is now saved to Mongo.
-
-=== Retrieving a Java from MongoDB ===
-
-Now let's look at the other direction: creating a Java object from a
document in the Mongo database. This is also simple. We just call the
fromDBObject() method on our Morphia instance, passing in the DBObject
retrieved from Mongo:
-
-{{{
-Morphia morphia = ...;
-Mongo mongo = ...;
-DB db = mongo.getDB("BlogSite");
-
-String blogEntryId = ...; // the ID of the blog entry we want to load
-
-// load the DBObject from a Mongo collection
-BasicDBObject blogEntryDbObj = (BasicDBObject)
db.getCollection("BlogEntries").findOne(new BasicDBObject("_id", new
ObjectId(blogEntryId));
-
-// and then map it to our BlogEntry object
-BlogEntry blogEntry = morphia.fromDBObject(BlogEntry.class,
blogEntryDbObj);
-}}}
-
-That's it! Morphia removes all the error prone boiler plate code you would
normally need to map to/from your Java object by hand.
-
-A much cleaner way of managing your objects in Mongo with Morphia is to
utilize the [DAOSupport DAO support]. That method abstracts Mongo and
Morphia inside a Data Access Object (DAO), so your business logic has no
dependencies on Morphia.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/MappingObjects here]
=======================================
--- /wiki/MongoNewsletterArticleDec2010.wiki Thu Dec 9 15:41:54 2010
+++ /wiki/MongoNewsletterArticleDec2010.wiki Mon Jul 22 09:35:40 2013
@@ -1,84 +1,1 @@
-#summary The morphia related article for the Dec 2010 MongoDB Newsletter
-
-= Be optimistic, but not *too* much =
-
-There are many ways to manage
[
http://en.wikipedia.org/wiki/Concurrency_control concurrency controls] for
MongoDB. One way that [
http://code.google.com/p/morphia Morphia] does this
is by supplying a special annotation, {{{@Version}}}.
[
http://code.google.com/p/morphia Morphia] is a lightweight, type safe, and
type preserving, java-based mapper for MongoDB; in simple terms it allows
you to save java objects to and from MongoDB, and without writing much
code. The [
http://code.google.com/p/morphia Morphia] {{{@Version}}}
annotation is used to provide optimistic locking when updating an Entity;
this makes sure that changes made by multiple clients don't stomp on each
other -- at least not without generating an error.
-
-This type of concurrency control will let anyone read the entity, but will
check when writes occur that no one has updated between your read and
update. To do this you just need a special field on the entity; we can
increment this field as each update happens to provide these assurances.
This concurrency model helps when you update a single entity at a time, but
not for multiple updates.
-
-There are also pessimistic (locking) models where an explicit lock can be
acquired before, or during, the update process. These generally perform
more poorly, have a higher management cost, and are more complicated to
implement, but they have many benefits as well. I will not address these
and I will continue to talk about optimistic and/or time-stamp based
algorithms.
-
-Now let's dive into the actual code. In the code, and descriptions, below
you can replace the word *entity* with *document* if you like. I will be
speaking in Java terms.
-
-== The Entity Definition (model) ==
-{{{
-
-class Person {
- @Id String name;
- String phone;
-
- @Version
- long version;
-...
-}
-}}}
-
-== The Plan ==
-Now that we have our class properly mocked up, and annotated, we can start
to create some test instances and check things out. The goal of this test
is to show that with a single line of code in our entity (model) we can
make sure that nobody accidentally saves over something that has already
been updated.
-
-=== Setup ===
-Now we create our [
http://code.google.com/p/morphia/wiki/Datastore
Datastore] which will used to access mongodb. We then create a {{{new
Person(...)}}} and save me.
-
-{{{
-Datastore ds = ...;
-
-Person me = new Person("Scott Hernandez");
-
-ds.save(me) // all good
-}}}
-
-After the {{{save(...)}}} has completed our person now has a value stored
in the {{{@Version}}} field which will be used by
[
http://code.google.com/p/morphia Morphia] to manage things for us. If you
look you will see that by default it is a counter set to the current
milliseconds, but it could be a mono-atomically increasing number as well.
-
-=== Handling The Error ===
-
-{{{
-Person meAgain = ds.get(Person.class, "Scott Hernandez");
-
-me.setPhone("111-376-7379");
-ds.save(me); // now "me" and "meAgain" are different versions
-
-try {
- ds.setPhone("123-376-7379");
- ds.save(meAgain);
-} catch (ConcurrentModificationException e) {
- // ooppsss... someone modified it since we got it.
- // try again, but this time get the new version to work from... or
notify the user.
-}
-}}}
-
-Now that we have created two instances of the same person, and updated
them one at a time, we can cause a {{{ConcurrentModificationException}}} to
be thrown. You can imagine that this might happens on different threads or
machines.
-
-== Under the Covers ==
-
-Deep, well not so deep, in the Morphia persistence code is a check to see
if there is a {{{@Version}}} field in the entity. If so, then the value is
added to the list of fields used to do the query part of the update.
Normally when you do a save it will just do an update based on the
{{{_id}}} field.
-
-Here is the "save" javascript from the shell:
-{{{
-> db.c.save
-function (obj) {
-... //insert or
- return this.update({_id:obj._id}, obj, true);
-}
-}}}
-
-To support the new version field we simply add it to the query on the
update. In addition we must increment the version to a new one. This
pseudo-code might give you the simple idea:
-
-{{{
-var oldVersion = obj.version;
-obj.version = newVersion;
-...update({_id:obj._id, version:obj.version}, obj);
-}}}
-
-== Wrap-up ==
-
-Using {{{@Version}}} is trivial in [
http://code.google.com/p/morphia
Morphia]. It provides additional concurrency control from what MongoDB
offers without costing anything but a little extra space per Entity and
very tiny bit of extra work on matching/updating. This type of optimistic
locking pattern is very easy for any framework to implement and solves many
problems that read-world developers have. Some frameworks not only support
optimistic, but also a form of pessimistic locking; you can create an
external document, a lock basically, to indicate that the update is in
process for some other document, like the
[
http://www.doctrine-project.org/projects/mongodb_odm/1.0/docs/reference/introduction/en
Doctrine PHP ODM] framework does. I'm sure that many mappers -- which
include Morphia, Doctrine and MongoKit, and more -- have implemented
optimistic concurrency controls like this.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/MongoNewsletterArticleDec2010 here]
=======================================
--- /wiki/MorphiaInUse.wiki Sun May 8 10:55:38 2011
+++ /wiki/MorphiaInUse.wiki Mon Jul 22 09:35:40 2013
@@ -1,19 +1,1 @@
-#summary People and places using morphia
-
-= Morphia in Action =
-
- * [
http://bugfix.me/ bugfix]
- * [
http://mashape.com/ mashape]
-
-= Articles/Blogs =
-
- *
[
http://storypodders.com/dasBlog/2010/10/18/UsingMongoDBAndMorphiaToPersistAndRetrievePOJOsNoSQL.aspx
Using MongoDB and Morphia to persist and retrieve POJO’s- NoSQL]
- * [
http://www.scalabiliti.com/blog/mongodb_and_morphia_performance
morphia performance blog post]
[
http://www.scalabiliti.com/blog/morphia_performance_revisited revisited]
- * [
http://jameswilliams.be/blog/entry/177 Morphia + Groovy]
- *
[
http://nosql.mypopescu.com/post/816470307/tutorial-mongodb-in-java#morphia_jpa-like
morphia mentioned in a comparison]
- * [
http://www.playframework.org/modules/morphia Play Framework with
MongoDB (Morphia)]
- *
[
http://sleeplessinslc.blogspot.com/2010/10/mongodb-with-morphia-example.html
another blog]
- *
[
http://it-republik.de/jaxenter/artikel/Morphia---POJO-Persistenz-mit-mongoDB-3372.html
german blog post]
- *
[
http://blog.adampresley.com/2010/my-grails-and-mongodb-experience-so-far/
grails morphia example]
- * [
http://blog.mashape.com/41639506 mashup blog entry]
- * [
http://github.com/xeraa/mongouk2011 Presentation + example project]
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/MorphiaInUse here]
=======================================
--- /wiki/Motivation.wiki Mon Dec 6 15:28:05 2010
+++ /wiki/Motivation.wiki Mon Jul 22 09:35:40 2013
@@ -1,22 +1,1 @@
-#summary The motivation behind Morphia.
-
-= Motivation =
-
-Many visions have been brought together on this project. As with any
project where there are many contributors this project has seen lots of
different ideas. The over-arching goal is to provide a fast, easy and
obvious way to use the strengths from java with the features of mongodb.
-
-Generally the motivation has come from wanting to work with
Plain-Old-Java-Objects (POJO) and to remove some of the knowledge needed to
store data in mongodb while providing more fluent and "javaesk" interfaces
to the data.
-
-The basic java driver provides a view of the data as one of nested
{{{Map<String, Object>}}} which is a very dynamic, but unfortunately less
java-like, view of data. The mongodb driver provides a very malleable and
consistent view of how to perform queries; however it is somewhat
complicated (and cumbersome), but is very complete. The goal of this
project is to keep all that control, and power, while making it much easier
to integrate with java's principles and best practices.
-
-The basic goals come down to these:
- * Type-safe/preserving: we deal with POJOs -- java classes and fields
- * Annotation based configuration (less code)
- * Easy to use [Query] interface (intuitive)
- * Flexibility in your domain objects (reduce the need for DTO/DMOs)
- * Fast enough never to give up on the items above to change your
programming style
-
-For example, if we're storing information about hotels, we're likely to
create a Hotel class, and add fields like title, description, address,
rating, pictures, etc.
-
-It is easy to instantiate Java classes and add data to the fields, but
when it comes to actually persisting the data we usually map the object to
an external data source (such as database, xml files, etc.). This often
involves a lot of error prone boiler plate code (e.g. mapping from JDBC
result set, XML elements, etc.). The same applies, of course, when we need
to map the Java object to the external data source: more boiler plate code.
-
-We already have good object mapping frameworks for relational databases
and JDBC, of JPA and Hibernate. The vision of Morphia is to provide
something similar for MongoDB (
http://mongodb.org).
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/Motivation here]
=======================================
--- /wiki/PropertyAnnotation.wiki Wed Oct 13 15:23:55 2010
+++ /wiki/PropertyAnnotation.wiki Mon Jul 22 09:35:40 2013
@@ -1,59 +1,1 @@
-#summary Annotating primitive and basic (type) fields.
-
-= Annotating primitive and basic type fields =
-
-To store primitive and basic type fields in Mongo, you don't need any
annotations:
-
-{{{
-...
-private int myInt;
-private Date myDate;
-private List<String> myStrings;
-private String[] stringArray;
-...
-}}}
-
-By default, Morphia will try to map all the supported basic and primitive
types to/from Mongo, including arrays of those types.
-
-MongoDB only has the following data types:
- * Integer (32-bit signed value)
- * Long (64-bit signed value)
- * Double (64-bit IEEE754 fp value)
- * String
-
-There are some conversions worth noting:
- * float -> double
- * byte -> int
- * short -> int
- * char -> String (l char)
-
-Also, depending on what exists in the your model and the datastore we will
try to convert things automagically. I mean, since there are only 3 number
types in MongoDB (32/64-bit signed, 64-bit FP) it is pretty easy to
up-convert.
-
-The following list defines what basic and primitive types can currently be
persisted:
-
- * enum (stored as String in Mongo)
- * java.util.Date (stored as ms since epoch UTC)
- * java.util.Locale (stored as String)
- * com.mongodb.DBRef
- * com.mongodb.ObjectId
-
-As we showed in the example above, Morphia can also store a
java.util.List, java.util.Set, and java.util.Map collections, and primitive
arrays of any supported types.
-
-If you want to exclude a field from being mapped to Mongo, use the
@Transient annotation:
-
-{{{
-import com.google.code.morphia.annotations.Transient;
-...
-@Transient private int myTransientInt;
-...
-}}}
-
-By default, Morphia uses the field name as the value name in Mongo. This
can be overridden by using the @Property annotation, and specifying a name:
-
-{{{
-import com.google.code.morphia.annotations.Property;
-...
-@Property("my_integer")
-private int myInt;
-...
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/PropertyAnnotation here]
=======================================
--- /wiki/Query.wiki Wed Nov 23 05:57:57 2011
+++ /wiki/Query.wiki Mon Jul 22 09:35:40 2013
@@ -1,236 +1,1 @@
-#summary How to Query
-
-<wiki:toc/>
-
-= Introduction =
-The Query interface is pretty straight forward. It allows for certain
filter criteria (based on fields), sorting, an offset, and limiting of the
number of results.
-
-The query implementation also implements the the {{{QueryResults}}}
interface which allows access to the data from the query.
-
-= Filter =
-
-The generic {{{.filter(criteria, value) }}} syntax is supported. The
criteria is a composite of the field name and the operator ("field >",
or "field in"). All criteria are implicitly combined with a logical "and".
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).filter("foo >", 12);
-
-}}}
-
-Finding entities where foo is between 12 and 30 would look like this:
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).filter("foo >", 12).filter("foo
<", 30);
-
-}}}
-
-== Operators ==
-
-The operators used in {{{filter(...)}}} match the MongoDB query operators
very closely.
-
-||operator||mongo op||
-|| = || $eq ||
-|| !=, <> || $ne ||
-|| >, <, >=,<= || $gt, $lt, $gte, $lte ||
-|| in || $in ||
-|| nin || $nin ||
-|| elem || $elemMatch ||
-|| exists || $exists ||
-|| all || $all ||
-|| size || $size ||
-|| ... || ... ||
-
-
-= Fluent Interface =
-
-Along with the {{{.filter(...)}}} method there are fluent query methods as
well. These provide a more readable (like in the english language sense)
form.
-
-The fluent interface works by starting with {{{field(name)}}}. Then any of
the following methods can be added to form the filtering part of the
criteria.
-
-{{{
-Query q = ds.createQuery(MyEntity.class).field("foo").equal(1);
-
-q.field("bar").greaterThan(12);
-q.field("bar").lessThan(40);
-
-}}}
-
-== Methods ==
-
-|| method || operation || comment ||
-||exists || $exists || ||
-||doesNotExist || $exists || ||
-||greaterThan, greaterThanOrEq, lessThan, lessThanOrEq || $gt, $gte, $lt,
$lte || ||
-||equal, notEqual || $eq, $ne || ||
-||hasThisOne || $eq || ||
-||hasAllOf || $all || ||
-||hasAnyOf || $in || ||
-||hasNoneOf || $nin || ||
-||hasThisElement || $elemMatch || ||
-||sizeEq || $size || ||
-
-=== Geo-spatial ===
-
-All of the geo-spatial query methods break down into "near, and within".
All of the {{{near}}} queries will produce results in order of distance,
closest first. All of the methods below also accept a final parameter of
{{{spherical}}} to indicate if they should use the new {{{$sphere}}} option.
-
-|| method || operation || comment ||
-||near(x,y) || $near || ||
-||near(x,y,r) || $near || (w/maxDistance of r) ||
-||within(x,y,r) || $within + $center || ||
-||within(x1,y1,x2,y2) || $within + $box || ||
-
-{{{
-@Entity
-static private class Place {
- @Id protected ObjectId id;
- protected String name = "";
- @Indexed(IndexDirection.GEO2D)
- protected double[] loc = null;
-
- public Place(String name, double[] loc) {
-
this.name = name;
- this.loc = loc; }
-
- private Place() {}
-}
-
-Place place1 = new Place("place1", new double[] {1,1});
-ds.save(place1);
-
-Place found = ds.find(Place.class).field("loc").near(0, 0).get();
-}}}
-
-=== Or ===
-
-Using the fluent query interface you can also do "or" queries like this:
-{{{
-Query<Person> q = ad.createQuery(Person.class);
-q.or(
- q.criteria("firstName").equal("scott"),
- q.criteria("lastName").equal("scott")
-);
-
-}}}
-
-*Note*: In this example the method {{{criteria}}} is used. It you use
{{{field}} as one of the {{{or}}} parameters then you will get a compiler
error.
-
-= Fields =
-
-Field names can be used much like they can in
[
http://www.mongodb.org/display/DOCS/Advanced+Queries native mongodb
queries], with
[
http://www.mongodb.org/display/DOCS/Dot+Notation+(Reaching+into+Objects) "dot"
notation].
-
-{{{
-
-Query q = ds.createQuery(Person.class).field("addresses.city").equal("San
Francisco");
-//or with filter, or with this helper method
-Query q = ds.find(Person.class, "addresses.city", "San Francisco");
-
-}}}
-
-= Validation =
-
-Validation is done on the field names, and data types used. If a field
name is not found on the java class specified in the query then an
exception is thrown. If the field name is in "dot" notation then each part
of the expression is checked against your java object graph (with the
exception of a map, where the key name is skipped).
-
-Problems in the data type (comparing the field type and parameter type)
are logged as warnings since it is possible that the server can coerce the
values, or that you meant to send something which didn't seem to make
sense; The server uses the byte representation of the parameter so some
values can match even if the data types are different (numbers for example).
-
-== Disabling Validation ==
-
-Validation can be disabled by calling {{{disableValidation()}}} as the
beginning of the query definition, or anywhere within you query.
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).disableValidation();
-
-//or it can be disabled for just one filter
-
-Query q =
ds.createQuery(MyEntity.class).disableValidation().filter("someOldField",
value).enableValidation().filter("realField", otherVal);
-
-}}}
-
-
-= Sort =
-You can sort by a field, or multiple fields in ascending or descending
order.
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).filter("foo >",
12).order("dateAdded");
-... // desc order
-Query q = ds.createQuery(MyEntity.class).filter("foo >",
12).order("-dateAdded");
-... // asc dateAdded, desc foo
-Query q = ds.createQuery(MyEntity.class).filter("foo >",
12).order("dateAdded, -foo");
-}}}
-
-= Limit =
-
-You can also limit for the number of elements.
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).filter("foo >", 12).limit(100);
-}}}
-
-= Offset (skip) =
-
-You can also ask the server to skip over a number of elements on the
server by specifying an offset value for the query. This will less
efficient than a range filter using some field, for pagination for example.
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).filter("foo >", 12).offset(1000);
-}}}
-
-= Ignoring Fields =
-
-MongoDB also supports only returning certain fields. This is a little
strange in application but it is an important way to trim parts off of
embedded graphs. This will lead to partial entities and should be used
sparingly, if at all.
-
-{{{
-Datastore ds = ...
-MyEntity e =
ds.createQuery(MyEntity.class).retrievedFields(true, "foo").get();
-
-val = e.getFoo(); // only field returned
-
-...
-
-MyEntity e =
ds.createQuery(MyEntity.class).retrievedFields(false, "foo").get();
-
-val = e.getFoo(); // only field not returned
-
-}}}
-
-The field name argument (the last arg) can be a list of strings or a
string array:
-{{{
-MyEntity e =
ds.createQuery(MyEntity.class).retrievedFields(true, "foo", "bar").get();
-
-val = e.getFoo(); // fields returned
-vak = e.getBar(); // fields returned
-
-}}}
-
-
-= Returning Data =
-
-To return your data just call one of the {{{QueryResults}}} methods. None
of these methods affect the Query. They will leave the Query alone so you
can continue to use it to retrieve new results by calling these methods
again.
-
-||method||does||
-|| get() || returns the first Entity -- using limit(1) ||
-|| asList() || return all items in a List -- could be costly with large
result sets ||
-|| fetch() || explicit method to get Iterable instance ||
-|| asKeyList() || return all items in a List of their {{{Key<T>}}} -- This
only retrieves the _id field from the server. ||
-|| fetchEmptyEntities() || Just like a {{{fetch()}}} but only retrieves,
and fills in the _id field. ||
-
-{{{
-Datastore ds = ...
-Query q = ds.createQuery(MyEntity.class).filter("foo >", 12);
-
-//single entity
-MyEntity e = q.get();
-
-e = q.sort("foo").get();
-
-//for
-for (MyEntity e : q)
- print(e);
-
-//list
-List<MyEntity> entities = q.asList();
-
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/Query here]
=======================================
--- /wiki/QuickStart.wiki Sat Nov 19 05:38:29 2011
+++ /wiki/QuickStart.wiki Mon Jul 22 09:35:40 2013
@@ -1,177 +1,1 @@
-#summary A quick 2 minute intro to Morphia.
-#labels Featured
-
-= Storing your POJOs in MongoDB? =
-
-Morphia makes that very easy. Here's what you need to do.
-== Libs ==
-
-Go take care of getting the [Dependencies] for your project.
-
-== Annotate your Java classes ==
-
-Let's imagine we have the following simple classes:
-
-{{{
-public class Hotel {
-
- private String name;
- private int stars;
- private Address address;
-
- // ... getters and setters
-}
-}}}
-
-and
-
-{{{
-public class Address {
-
- private String street;
- private String city;
- private String postCode;
- private String country;
-
- // ... getters and setters
-}
-}}}
-
-We want to save instances of these objects to MongoDB. All we need to do
is add the Morphia annotations to the class fields we want to persist:
-
-{{{
-import com.google.code.morphia.annotations.Entity;
-import com.google.code.morphia.annotations.Embedded;
-import
com.google.code.morphia.annotations.Id;
-import com.google.code.morphia.annotations.Property;
-import org.bson.types.ObjectId;
-
-@Entity
-public class Hotel {
-
- @Id private ObjectId id;
-
- private String name;
- private int stars;
-
- @Embedded
- private Address address;
-
- // ... getters and setters
-}
-}}}
-
-and
-
-{{{
-import com.google.code.morphia.annotations.Embedded;
-
-@Embedded
-public class Address {
-
- private String street;
- private String city;
- private String postCode;
- private String country;
-
- // ... getters and setters
-}
-}}}
-
-We've annotated Hotel with @Entity, and Address with @Embedded since the
Address is an object dependent on Hotel (and does not have a life outside
the Hotel).
-
-You can see that all the basic fields are automatically mapped by Morphia.
If you want to exclude a field, just annotate it with @Transient.
-
-Also note that we had to add a new field "id" to our Hotel class. The "id"
value can be any persist-able type; like an int, uuid, or other object. If
you want an auto-generated value just declare it as an {{{ObjectId}}}. If
you don't use an {{{ObjectId}}} you must set the value before saving.
-
-== Prepare the framework ==
-
-Next, we create an instance of Morphia, and map the classes we want to use:
-
-{{{
-import com.google.code.morphia.Morphia;
-...
-Mongo mongo = ...;
-Morphia morphia = new Morphia();
-morphia.map(Hotel.class).map(Address.class);
-Datastore ds = morphia.createDatastore(mongo, "my_database");
-...
-}}}
-
-Mapping the classes at the beginning of your application is a good
practice. It allows the system to validate your classes and prepare for
storing the data, and retrieving it. You can also do a few other that are
only required once at this time.
-
-== Persisting POJOs ==
-
-Now we can use the Datastore instance to save classes with MongoDB. To
save a Hotel in Mongo:
-
-{{{
-Hotel hotel = new Hotel();
-hotel.setName("My Hotel");
-hotel.setStars(4);
-
-Address address = new Address();
-address.setStreet("123 Some street");
-address.setCity("Some city");
-address.setPostCode("123 456");
-address.setCountry("Some country");
-
-//set address
-hotel.setAddress(address);
-
-Morphia morphia = ...;
-Datastore ds = morphia.createDatastore("testDB");
-
-// Save the POJO
-ds.save(hotel);
-
-}}}
-
-Loading a Hotel from Mongo is also simple:
-
-{{{
-Morphia morphia = ...;
-Datastore ds = morphia.createDatastore("testDB");
-
-String hotelId = ...; // the ID of the hotel we want to load
-
-// and then map it to our Hotel object
-Hotel hotel = ds.get(Hotel.class, hotelId);
-
-}}}
-
-Using a query is just as simple as loading Hotel:
-
-{{{
-Morphia morphia = ...;
-Datastore ds = morphia.createDatastore("testDB");
-
-// it is easy to get four-star hotels.
-List<Hotel> fourStarHotels = ds.find(Hotel.class, "stars >=", 4).asList();
-//or
-fourStarHotels =
ds.find(Hotel.class).field("stars").greaterThenEq(4).asList();
-
-}}}
-
-
-== Data Access Object (DAO) Support ==
-
-To take advantage of the basic Morphia DAO support:
-
-{{{
-import com.google.code.morphia.Morphia;
-import com.google.code.morphia.dao.BasicDAO;
-import com.mongodb.DBCollection;
-import com.mongodb.Mongo;
-
-public class HotelDAO extends BasicDAO<Hotel, String> {
- public HotelDAO(Morphia morphia, Mongo mongo ) {
- super(mongo, morphia, "myDB");
- }
-}
-
-HotelDAO hDAO = ...
-
-hDAO.save(new Hotel(...));
-}}}
-
-In a web application environment, we would probably inject the Mongo,
Morphia, and Datastore instances into a DAO/Service, and then inject the
that into a controller, so the controller would never directly deal with
Mongo or Morphia.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/QuickStart here]
=======================================
--- /wiki/ReferenceAnnotation.wiki Tue Jan 18 11:14:36 2011
+++ /wiki/ReferenceAnnotation.wiki Mon Jul 22 09:35:40 2013
@@ -1,83 +1,1 @@
-#summary Describes how to annotate fields with referenced objects.
-
-= Referencing Objects =
-
-Mongo references are references from one document (object) to another
within the database. Consider the following classes:
-
-{{{
-public class BlogEntry {
-
- private String title;
- private Date publishDate;
- private String body;
-
- private Author author;
-
- // getters and setters
-}
-
-...
-
-public class Author {
-
- private String username;
- private String fullName;
- private String emailAddress;
-
- // getters and setters
-}
-}}}
-
-The question here is: _How do we annotate the author field in BlogEntry?_
We could of course use the @Embedded annotation, but that does not make
sense here, since we don't want to store the Author with every BlogEntry
instance. Instead we want multiple blog entries to reference a single
Author document in Mongo.
-
-For this case we use the @Reference annotation:
-
-{{{
-import com.google.code.morphia.annotations.Entity;
-import com.google.code.morphia.annotations.Embedded;
-import
com.google.code.morphia.annotations.Id;
-import com.google.code.morphia.annotations.Reference;
-import com.google.code.morphia.annotations.Property;
-
-@Entity
-public class BlogEntry {
-
- @Id
- private ObjectId id;
-
- private String title;
- private Date publishDate;
- private String body;
-
- @Reference
- private Author author;
-
- // getters and setters
-}
-
-...
-
-@Entity
-public class Author {
-
- @Id
- private ObjectId id;
-
- private String username;
- private String fullName;
- private String emailAddress;
-
- // getters and setters
-}
-}}}
-
-One very important thing to mention when working with references: _The
referenced object must have been saved in Mongo before saving the object
referencing it._
-
-This makes sense, really. In terms of the example above, it means that you
must already have an Author in the database before you can create a
BlogEntry.
-
-By default, Morphia uses the field name as the value name in Mongo. This
can be overridden by specifying a name on the @Reference annotation:
-
-{{{
- @Reference("blog_authors")
- private List<Author> authors;
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/ReferenceAnnotation here]
=======================================
--- /wiki/ReleaseNotes.wiki Fri Apr 12 08:32:51 2013
+++ /wiki/ReleaseNotes.wiki Mon Jul 22 09:35:40 2013
@@ -1,124 +1,1 @@
-#summary Morphia Release Notes
-#labels Featured
-*Releases*:
-<wiki:toc/>
-
-= 1.00 =
-*unreleased*:
-
-= 0.101.0 =
-*unreleased*:
- * *Requires* mongodb java driver 2.10.1+
- * Fixed timeout Enable/disable, was opposite of what it says
- * Fix geospatial sphere option
- * Fix validation for Index on Embedded object fields in an array
- * Validate/Translate sort/order in Query
- * And more...
https://code.google.com/p/morphia/issues/list?can=1&q=label%3AMilestone-Release0.99.1
-
-= 0.99.1=
-*unreleased*:
- * *Requires* mongodb java driver 2.7+
- * Added {{{Helper}}} object to get Query/Datastore internals useful for
the driver methods on DB/DBCollection/DBCursor/...
- * {{{GridFS}}} support for mappings
- * Validate and translate sort fields.
-
-= 0.99 =
-*2011-01-26*:
- * *Requires* mongodb java driver 2.3+
- * Sparse index support in {{{@Indexed}}} (for mongodb 1.7.4+)
- * Mapreduce support (no temp collection support -- always specifies out)
- * {{{java.sql.Timestamp}}} support
- * {{{findAndModify}}} support for createIfMissing (upsert)
- * [Updating Update] supports {{{@Refence}}}/{{{Key<T>}}} fields better
- * [Updating Update] validation improvements
- * GWT Support for {{{DBRef/ObjectId/Key<T>}}}
- * insert/delete operations return {{{WriteResult}}}
- * cleaned up maven versions in repo
- * Misc bugs and improvements
-
-= 0.98 =
-*2010-11-30*:
- * *Requires* mongodb java driver 2.3+
- * DOA is now an interface and moved to dao package, along with BasicDAO
- * Validation is now done on {{{UpdateOperations}}} for updates
- * Fluent query interface now support geo-queries (near/within +
spherical)
- * Merge support (just update fields, instead of replacing like save)
- * {{{@ConstructorArgs("field1","field2")}}}: Embedded objects can now
get constructor args from the db (currently support simple types only)
- * Parameterized super-class support: {{{class MyEntity extends
BaseEntity<String> {... }}}
- * Added support for isolation on updates,
{{{UpdateOperations.isIsolated()}}}; multi updates will happen without
yielding.
- * Support for migrating from a single item to an array/collection.
- * various bugs ;)
-
-= 0.97.1 =
-*2010-11-22*:
- * Bug fixes:
- * Issue #161
- * Issue #163
- * Issue #164
- * Issue #166
-
-= 0.97 =
-*2010-11-12*:
- * *Requires* mongodb java driver 2.2+
- * "or" query support (experimental)
- * Nested collections/maps
- * {{{@Indexes({@Index("field1, -field2")})}}} support (declared compound
index support)
- * {{{@Entity(concern="safe")}}} support ({{{WriteConcern.""}}})
- * {{{slaveOk()}}} query support (and {{{@Entity}}})
- * {{{Query.noTimeout}}}
- * {{{Query.snapshotMode}}}
- * {{{ObjectId}}} map key supported: {{{Map<ObjectId, Object>}}} (Note:
The {{{ObjectId}}} is converted to string in mongodb)
- * Background indexing: {{{@Indexed(background=true)}}} +
{{{Datastore.ensureIndex(es)(background)}}}
- * Update now adds {{{className}}} fields for entities in
{{{UpdateOperations.set/addAll/add}}}
- * {{{@Id}}} field updated for updateFirst when inserted with
{{{WriteConcern.Safe}}}
- * {{{@Converters}}} - registration for converters
- * {{{@Indexed}}} now works on embedded classes
- * {{{@EntityListeners}}} now created only once per type
- * {{{ObjectFactory}}} used to create entities, List/Map/Set defaults,
converters and {{{@EntityListeners}}} classes
-
-
-
-= 0.96 =
-*2010-10-06*:
- * Added support for {{{@Id Map id}}} ; the Map part
- * fixed bug with query {{{doesNotExist()}}}
- * Java-field name or the saved field name can be used in [Query]
- * {{{UpdateResults}}} now only called {{{WriteResult.getLastError()}}}
when methods called
- * various Converter enhancements (support in lists and maps with
@Embedded)
- * 1.5 Java support back
-
-= 0.95 =
-*2010-08-23*:
- * *Requires* mongodb java driver 2.1
- * {{{WriteConcern}}} defaults to Safe (Strict) (see
{{{Datastore.set/getWriteConcern()}}} to change)
- * Write operation related methods now have overload with
{{{WriteConcern}}} param.
- * Trace level logging for queries/updates/findAnd{{{*}}}.
- * Extended cache-scope to resolve non-lazy referenced Entities within
the scope of one query
- * Fixed bug in {{{UpdateOperations}}} where {{{add(..)}}} was acting
like {{{$set}}}
- * Added basic support for {{{@NotSaved}}} (but will still load values)
- * Removed implicit conversions from String -> {{{ObjectId}}}; please use
{{{ObjectId}}} directly; *Breaking Change*
- * Added javadocs and sources to maven repo
- * Changed ensureIndex methods sigs to use arrays (to preserve ordering);
*Breaking Change*
- * Added {{{starts/endsWith[IgnoreCase]}}} to [Query] (only
{{{StartWith}}} uses index)
- * Better validation of query values (null/empty)
- * New internal logging abstraction (to support better perf./parity for
other loggers)
- * bug fixes
-
-= 0.94 =
-*2010-07-14*:
- * Added support for
[
http://code.google.com/p/morphia/issues/detail?id=37 custom @Id classes]
(embed complex type)
- * Added {{{@AlsoLoad}}} to load renamed fields
- * {{{UpdateOperations}}} now generic (_breaking change_)
- * Datastore.createUpdateOperation({{{Class<T>}}}) (_breaking change_)
- * Added {{{Datastore.findAndModify/findAndDelete}}}
- * Added {{{@Entity}}} attribute of {{{noStoredClassname[=true]}}}
- * ([
http://code.google.com/p/morphia/issues/detail?id=73 Issue73-Add
Auth Support to Morphia.createDatastore(...)])
- * Added startsWith to query filters
- * Better query validation error messages and less false-positives
- * Bug fixes
-
-= 0.93 =
-*2010-06-13*:
- * Requires mongodb java 2.0 driver
- * Rewrote must of the framework from 0.92 state.
- * much, much more...
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/ReleaseNotes here]
=======================================
--- /wiki/ReleaseProcess.wiki Wed Apr 10 14:16:08 2013
+++ /wiki/ReleaseProcess.wiki Mon Jul 22 09:35:40 2013
@@ -1,26 +1,1 @@
-#summary The morphia release process
-
-= The Morphia Release Process =
-
-== Pre-Release ==
-
- * Before any release (snapshot) or pre-release (like a release
candidate) will be done.
- * Follow the steps same as the Release, except
- * Don't announce on mongodb-announce
-
-== Release ==
-
-=== Preparation ===
- * Update all pom.xml files to new version (.100) + increment parent
number
- * Update java driver dependency (ex. 2.10.x)
- * Update ReleaseNotes
-=== Deployment ===
- * Upload new release to downloads
- * Add to featured
- * Remove featured from old version (including snapshots and RCs)
- * Upload new release to Maven Central
- * <Include directions>
-=== Announcement ===
- * Announce to be officially posted on:
- * [
http://groups.google.com/group/morphia morphia list]
- * [
http://groups.google.com/group/mongodb-announce mongodb-announce
list]
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/ReleaseProcess here]
=======================================
--- /wiki/SLF4JExtension.wiki Sat Feb 19 14:19:56 2011
+++ /wiki/SLF4JExtension.wiki Mon Jul 22 09:35:40 2013
@@ -1,30 +1,1 @@
-#summary SLF4J Logging Extension
-#labels Extension
-
-= Introduction =
-
-This is a simple extension to Morphia to redirect logging to SFL4J.
-
-= Using =
-Add this at the start of your application. It is done once, statically.
-
-{{{
-MorphiaLoggerFactory.registerLogger(SLF4JLoggerImplFactory.class);
-}}}
-
-== Dependencies ==
-
-=== Manual ===
- * [
http://www.slf4j.org SLF4J]
-
-=== Maven ===
- * If you use Maven2 to manage your project, you can reference Morphia as
a dependency.
- * Repo: {{{
http://morphia.googlecode.com/svn/mavenrepo/}}}
- * Project Settings:
-{{{
-<dependency>
- <groupId>com.google.code.morphia</groupId>
- <artifactId>morphia-logging-slf4j</artifactId>
- <version>0.99</version>
-</dependency>
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/SLF4JExtension here]
=======================================
--- /wiki/SoftwareUsed.wiki Tue Oct 5 15:35:33 2010
+++ /wiki/SoftwareUsed.wiki Mon Jul 22 09:35:40 2013
@@ -1,17 +1,1 @@
-#summary Software we use....
-
-= Software Used to Develop Morphia =
-
-== Building ==
- * Maven
- * SVN
-
-== IDE ==
-
- * Eclipse
-
-== {{{YourKit}}} Profiler ==
-{{{YourKit}}} is kindly supporting open source projects with its
full-featured Java Profiler.
-{{{YourKit}}}, LLC is the creator of innovative and intelligent tools for
profiling
-Java and .NET applications. Take a look at {{{YourKit}}}'s leading
software products:[
http://www.yourkit.com/java/profiler/index.jsp YourKit
Java Profiler] and
-[
http://www.yourkit.com/.net/profiler/index.jsp YourKit .NET Profiler].
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/SoftwareUsed here]
=======================================
--- /wiki/TableOfContents.wiki Sat Feb 19 13:33:56 2011
+++ /wiki/TableOfContents.wiki Mon Jul 22 09:35:40 2013
@@ -1,27 +1,1 @@
-#summary Morphia documentation outline for the docreader.
- * [QuickStart The 2 minute intro]
- * User's Guide
- * [Motivation Motivation]
- * [GettingStarted Getting Started]
- * [Dependencies]
- * [Datastore Datastore Interface]
- * [Query Query Interface]
- * [LifecycleMethods Entity Lifecycle]
- * [AllAnnotations Annotations]
- * [EntityAnnotation Defining your Entity]
- * [PropertyAnnotation Basic type annotation]
- * [EmbeddedAnnotation Embedded Annotation]
- * [ReferenceAnnotation Referencing/Linking]
- * [UsingCollections Lists, Sets, and Maps]
- * Extensions
- * [ValidationExtension Validation]
- * [SLF4JExtension SLF4J Logging]
- * [JRebel JRebel extension]
- * GoogleWebToolkit
- * Manually Mapping objects to/from MongoDB (DBObjects)
- * [MappingObjects Using the Morphia instance]
- * [UsingInterfaces Programming to interfaces]
- * [DAOSupport Using Data Access Objects (DAO)]
- * [FrequentlyAskedQuestions FAQ]
-
-<wiki:gadget
url="
http://www.ohloh.net/p/morphia/widgets/project_users.xml" height="100"
border="0" />
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/TableOfContents here]
=======================================
--- /wiki/Updating.wiki Sun Jun 12 08:53:32 2011
+++ /wiki/Updating.wiki Mon Jul 22 09:35:40 2013
@@ -1,297 +1,1 @@
-#summary How to update data
-
-<wiki:toc/>
-
-= Introduction =
-
-There are two basic ways to update your data. You can either insert/save a
whole Entity, or issue an update operation. We will be talking about the
latter below.
-
-= Updating (on the server) =
-
-When you call the update method on the [Datastore] you are issuing a
command to the server to change existing data, in general.
-
-[
http://www.mongodb.org/display/DOCS/Updating MongoDB Docs on Updating]
-
-{{{
-interface Datastore {
-...
-
- /** updates all entities found with the operations*/
- <T> UpdateResults<T> update(Query<T> query, UpdateOperations<T> ops);
- /** updates all entities found with the operations; if nothing is found
insert the update as an entity if "createIfMissing" is true*/
- <T> UpdateResults<T> update(Query<T> query, UpdateOperations<T> ops,
boolean createIfMissing);
- /** updates the first entity found with the operations*/
- <T> UpdateResults<T> updateFirst(Query<T> query, UpdateOperations<T> ops);
- /** updates the first entity found with the operations; if nothing is
found insert the update as an entity if "createIfMissing" is true*/
- <T> UpdateResults<T> updateFirst(Query<T> query, UpdateOperations<T> ops,
boolean createIfMissing);
- /** updates the first entity found with the operations; if nothing is
found insert the update as an entity if "createIfMissing" is true*/
- <T> UpdateResults<T> updateFirst(Query<T> query, T entity, boolean
createIfMissing);
-}
-public interface UpdateOperations<T> {
- /** sets the field value */
- UpdateOperations<T> set(String fieldExpr, Object value);
- /** removes the field */
- UpdateOperations<T> unset(String fieldExpr);
-
- /** adds the value to an array field*/
- UpdateOperations<T> add(String fieldExpr, Object value);
- UpdateOperations<T> add(String fieldExpr, Object value, boolean
addDups);
- /** adds the values to an array field*/
- UpdateOperations<T> addAll(String fieldExpr, List<?> values,
boolean addDups);
-
- /** removes the first value from the array*/
- UpdateOperations<T> removeFirst(String fieldExpr);
- /** removes the last value from the array*/
- UpdateOperations<T> removeLast(String fieldExpr);
- /** removes the value from the array field*/
- UpdateOperations<T> removeAll(String fieldExpr, Object value);
- /** removes the values from the array field*/
- UpdateOperations<T> removeAll(String fieldExpr, List<?> values);
-
- /** decrements the numeric field by 1*/
- UpdateOperations<T> dec(String fieldExpr);
- /** increments the numeric field by 1*/
- UpdateOperations<T> inc(String fieldExpr);
- /** increments the numeric field by value (negatives are allowed)*/
- UpdateOperations<T> inc(String fieldExpr, Number value);
-}
-
-}}}
-
-== The Field Expression ==
-
-The field expression that is used for all operations can be either a
single field name, or any dot-notation form (for embedded elements). You
can also use the positional operator ($) in the field expression. There is
no validation on the field expression so you can put anything in there that
is valid on the server.
-
-== Samples initialization ==
-
-All of the code samples below create the connection and morphia instance
using the following code:
-
-{{{
-Morphia morphia = new Morphia();
-morphia.map(Hotel.class).map(Address.class);
-Datastore datastore = morphia.createDatastore("MorphiaSampleDb");
-Hotel hotel = new Hotel("Fairmont", 3, new Address("1 Rideau
Street", "Ottawa", "K1N8S7", "Canada"));
-datastore.save(hotel);
-UpdateOperations<Hotel> ops;
-
-// This query will be used in the samples to restrict the update
operations to only the hotel we just created.
-// If this was not supplied, by default the update() operates on all
documents in the collection.
-// We could use any field here but _id will be unique and mongodb by
default puts an index on the _id field so this should be fast!
-Query<Hotel> updateQuery =
datastore.createQuery(Hotel.class).field("_id").equal(hotel.getId());
-
-// The Mapper class also provides a public static of the default _id field
name for us...
-Query<Hotel> updateQuery =
datastore.createQuery(Hotel.class).field(Mapper.ID_KEY).equal(hotel.getId());
-
-}}}
-
-*note the use of _equal()_ NOT _equals()_*
-
-{{{
-@Entity("hotels")
-public class Hotel
-{
- @Id
- private ObjectId id;
-
- private String name;
- private int stars;
-
- @Embedded
- private Address address;
-
- @Embedded
- List<Integer> roomNumbers = new ArrayList<Integer>();
-
- // ... getters and setters
-}
-
-@Embedded
-public class Address
-{
- private String street;
- private String city;
- private String postalCode;
- private String country;
-
- // ... getters and setters
-}
-}}}
-
-== set/unset ==
-
-{{{
-// change the name of the hotel
-ops = datastore.createUpdateOperations(Hotel.class).set("name", "Fairmont
Chateau Laurier");
-datastore.update(updateQuery, ops);
-
-// also works for embedded documents, change the name of the city in the
address
-ops =
datastore.createUpdateOperations(Hotel.class).set("address.city", "Ottawa");
-datastore.update(updateQuery, ops);
-
-// remove the name property from the document
-// causes the next load of the Hotel to have name = null
-ops = datastore.createUpdateOperations(Hotel.class).unset("name");
-datastore.update(updateQuery, ops);
-}}}
-
-== inc/dec ==
-{{{
-// increment 'stars' by 1
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars");
-datastore.update(updateQuery, ops);
-
-// increment 'stars' by 4
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 4);
-datastore.update(updateQuery, ops);
-
-// decrement 'stars' by 1
-ops = datastore.createUpdateOperations(Hotel.class).dec("stars"); // same
as .inc("stars", -1)
-datastore.update(updateQuery, ops);
-
-// decrement 'stars' by 4
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars", -4);
-datastore.update(updateQuery, ops);
-}}}
-
-== add/All ==
-{{{
-
-// push a value onto an array() (+v 0.95)
-// same as .add("roomNumbers", 11, false)
-ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11);
-datastore.update(updateQuery, ops); // [ 11 ]
-
-}}}
-
-Performing array operations on a non-array property causes mongodb to
throw an error.
-
-{{{
-
-ops = datastore.createUpdateOperations(Hotel.class).set("roomNumbers", 11);
-datastore.update(updateQuery, ops);
-
-// causes error since 'roomNumbers' is not an array at this point
-ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11,
false);
-datastore.update(updateQuery, ops); // causes error
-
-// delete the property
-ops = datastore.createUpdateOperations(Hotel.class).unset("roomNumbers");
-datastore.update(updateQuery, ops);
-
-// use the 3rd parameter to add duplicates
-
-// add to end of array, same as add()
-ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11,
false);
-datastore.update(updateQuery, ops); // [ 11 ]
-
-// no change since its a duplicate... doesn't cause error
-ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11,
false);
-datastore.update(updateQuery, ops); // [ 11 ]
-
-// push onto the end of the array
-ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 12,
false);
-datastore.update(updateQuery, ops); // [ 11, 12 ]
-
-// add even if its a duplicate
-ops = datastore.createUpdateOperations(Hotel.class).add("roomNumbers", 11,
true);
-datastore.update(updateQuery, ops); // [ 11, 12, 11 ]
-}}}
-
-== removeFirst/Last/All ==
-{{{
-
-//given roomNumbers = [ 1, 2, 3 ]
-ops =
datastore.createUpdateOperations(Hotel.class).removeFirst("roomNumbers");
-datastore.update(updateQuery, ops); // [ 2, 3 ]
-
-
-//given roomNumbers = [ 1, 2, 3 ]
-ops =
datastore.createUpdateOperations(Hotel.class).removeLast("roomNumbers");
-datastore.update(updateQuery, ops); // [ 1, 2 ]
-ops =
datastore.createUpdateOperations(Hotel.class).removeLast("roomNumbers");
-datastore.update(updateQuery, ops); // [ 1 ]
-ops =
datastore.createUpdateOperations(Hotel.class).removeLast("roomNumbers");
-datastore.update(updateQuery, ops); // [] empty array
-
-
-//given roomNumbers = [ 1, 2, 3, 3 ]
-ops =
datastore.createUpdateOperations(Hotel.class).removeAll("roomNumbers", 3);
-datastore.update(updateQuery, ops); // [ 1, 2 ]
-
-//given roomNumbers = [ 1, 2, 3, 3 ]
-ops =
datastore.createUpdateOperations(Hotel.class).removeAll("roomNumbers",
Arrays.asList(2, 3));
-datastore.update(updateQuery, ops); // [ 1 ]
-}}}
-
-== Multiple Operations ==
-
-You can also perform multiple update operations within a single update.
-
-{{{
-
-//set city to Ottawa and increment stars by 1
-ops =
datastore.createUpdateOperations(Hotel.class).set("city", "Ottawa").inc("stars");
-datastore.update(updateQuery, ops);
-
-//if you perform multiple operations in one command on the same property,
results will vary
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars",
50).inc("stars"); //increments by 1
-ops =
datastore.createUpdateOperations(Hotel.class).inc("stars").inc("stars",
50); //increments by 50
-
-//you can't apply conflicting operations to the same property
-ops = datastore.createUpdateOperations(Hotel.class).set("stars",
1).inc("stars", 50); //causes error
-
-}}}
-
-== updateFirst method ==
-
-In the default driver and shell this is the default behavior. In Morphia
we feel like updating all the results of the query is a better default (see
below).
-
-{ name: "Fairmont", stars: 5}, { name: "Last Chance", stars: 3 }
-
-{{{
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50);
-
-// (+v 0.95 now takes into account the order())
-// morphia exposes a specific updateFirst to update only the first hotel
matching the query
-datastore.updateFirst(datastore.find(Hotel.class).order("stars"), ops);
// update only Last Chance
-datastore.updateFirst(datastore.find(Hotel.class).order("-stars"), ops);
// update only Fairmont
-}}}
-
-{{{
-//default shell version is to match first
-//shell version has a multi to indicate to update all matches, not just
first
-//to mimic morphia operation, set multi = false
-db.collection.update( criteria, objNew, upsert, multi );
-}}}
-
-== update method ==
-{{{
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50);
-
-// morphia default update is to update all the hotels
-datastore.update(datastore.createQuery(Hotel.class), ops); //increments
all hotels
-
-}}}
-
-{{{
-//equivalent morphia shell version is... upsert = false, multi = true
-db.collection.update( criteria, objNew, false, true );
-}}}
-
-=== createIfMissing (overload parameter)===
-
-all of the update methods are overloaded and accept a "createIfMissing"
parameter
-
-{{{
-ops = datastore.createUpdateOperations(Hotel.class).inc("stars", 50);
-
-//update, if not found create it
-datastore.updateFirst(datastore.createQuery(Hotel.class).field("stars").greaterThan(100),
ops,
true);
-
-// creates { "_id" : ObjectId("4c60629d2f1200000000161d"), "stars" : 50 }
-}}}
-
-{{{
-//equivalent morphia shell version is... upsert = true
-db.collection.update( criteria, objNew, true, multi );
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/Updating here]
=======================================
--- /wiki/UsingCollections.wiki Mon Dec 6 15:34:12 2010
+++ /wiki/UsingCollections.wiki Mon Jul 22 09:35:40 2013
@@ -1,37 +1,1 @@
-#summary Using Lists, Sets, and Maps.
-
-= Using Collections =
-
-Morphia supports collections (List, Set, Map) and arrays (Integer[]).
-
-{{{
-...
-
-private Set<String> tags;
-
-private Map<String,Translation> translations;
-
-@Reference
-private List<Article> relatedArticles;
-...
-}}}
-
-Morphia will use the following implementations (by default) when creating
collections:
- * {{{java.util.ArrayList}}} for List
- * {{{java.util.HashSet}}} for Set
- * {{{java.util.HashMap}}} for Map
-
-If you want to use another implementation, you can override this on the
annotations:
-
-{{{
-...
-@Property(concreteClass = java.util.TreeSet.class)
-private Set<String> tags;
-
-@Embedded(concreteClass = java.util.TreeMap.class)
-private Map<String,Translation> translations;
-
-@Reference(concreteClass = java.util.Vector.class)
-private List<Article> relatedArticles;
-...
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/UsingCollections here]
=======================================
--- /wiki/UsingInterfaces.wiki Fri Mar 26 12:56:11 2010
+++ /wiki/UsingInterfaces.wiki Mon Jul 22 09:35:40 2013
@@ -1,78 +1,1 @@
-#summary Mapping to interfaces.
-
-= Programming to Interfaces =
-
-In our domain objects, we are often dealing with interfaces. We therefore
do not necessarily know the exact implementation type at compile time.
Consider the following classes:
-
-{{{
-public interface Shape {
- public double getArea();
-}
-
-...
-
-public class Rectangle implements Shape {
- private double height;
- private double width;
-
- public Rectangle() {}
-
- public Rectangle(double height, double width) {
- this.height = height;
- this.width = width;
- }
-
- @Override
- public double getArea() {
- return height * width;
- }
-}
-
-...
-
-public class Circle implements Shape {
- ...
-}
-
-...
-
-public class ShapeContainer {
- private List<Shape> shapes;
- ...
-}
-}}}
-
-Now we want to store the Shape Container in Mongo. The only problem for
Morphia when dealing with interfaces is knowing which implementation class
to instantiate. That is, when retrieving the first shape from Mongo, how
does Morphia know whether to map it to a Rectangle or a Circle?
-
-Morphia solves this by storing a value in the Mongo document,
called "className", which holds the full class name of the Java object
being stored in the document.
-
-We just need to make sure that all the implementation classes are added to
the Morphia instance:
-
-{{{
- Morphia morphia = new Morphia();
- morphia.map(Circle.class)
- .map(Rectangle.class)
- .map(ShapeShifter.class);
-}}}
-
-The shape container class can store the shape list as an embedded object:
-
-{{{
-public class ShapeContainer {
- @Embedded
- private List<Shape> shapes;
- ...
-}
-}}}
-
-...or as a list of references:
-
-{{{
-public class ShapeContainer {
- @Reference
- private List<Shape> shapes;
- ...
-}
-}}}
-
-So to summarize, Morphia makes programming to interfaces quite easy.
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/UsingInterfaces here]
=======================================
--- /wiki/UsingMorphia.wiki Wed Dec 28 08:00:01 2011
+++ /wiki/UsingMorphia.wiki Mon Jul 22 09:35:40 2013
@@ -1,9 +1,1 @@
-#summary Projects/Companies using Morphia
-
-= Who is using morphia? =
-The following projects and/or companies are using morphia for their
persistence needs.
-
- * Shutterfly
- * [
http://bugfix.me/ Bugfix.me], desktop based Bugtracker
- * [
http://www.bookdiscounter.nl/ Bookdiscounter] A book price comparison
website in The Netherlands
- * Many more...
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/UsingMorphia here]
=======================================
--- /wiki/ValidationExtension.wiki Sat Feb 19 15:20:35 2011
+++ /wiki/ValidationExtension.wiki Mon Jul 22 09:35:40 2013
@@ -1,53 +1,1 @@
-#summary JSR303 Validation Extension
-#labels Extension
-
-= Introduction =
-
-This is a simple extension to Morphia to process JSR303 Validation
Annotations.
-
-= Using =
-Add this at the start of your application (or wherever you create your
morphia instances).
-
-{{{
-new ValidationExtension(morphia);
-}}}
-
-== Example ==
-
-Here is a simple example using (as an example) Hibernate validation:
-
-{{{
-...
-import org.hibernate.validator.constraints.Email;
-...
-
-@Entity
-public class Userlike {
- @Id ObjectId id;
- @Email String email;
-}
-
-}}}
-
-= Implementation =
-
-This is a lightweight wrapper around the JSR303 API. It installs a simple
global entity interceptor which listens to all [LifecycleMethods life-cycle
methods] needed for validation. You can use any implementation of JSR303 by
just adding it to the classpath.
-
-You can look at the code
[
http://code.google.com/p/morphia/source/browse/trunk/validation/src/main/java/com/google/code/morphia/validation/MorphiaValidation.java
here].
-
-== Dependencies ==
-
-=== Manual ===
- * [
http://www.hibernate.org/subprojects/validator.html Hibernate
Validation](4.1.0)
-
-=== Maven ===
- * If you use Maven2 to manage your project, you can reference Morphia as
a dependency.
- * Repo: {{{
http://morphia.googlecode.com/svn/mavenrepo/}}}
- * Project Settings:
-{{{
-<dependency>
- <groupId>com.google.code.morphia</groupId>
- <artifactId>validation</artifactId>
- <version>0.99</version>
-</dependency>
-}}}
+This project has moved to github. You can find the new documentation
[
https://github.com/mongodb/morphia/wiki/ValidationExtension here]