[2.0] New MongoDB module for Play 2.0

5,665 views
Skip to first unread message

jroper

unread,
Mar 16, 2012, 7:32:38 AM3/16/12
to play-framework
I'm pleased to announce a new MongoDB module for Play 2.0. This
module uses the mongo-jackson-mapper:

http://vznet.github.com/mongo-jackson-mapper

which uses Jackson annotations to map Java/Scala objects to/from
MongoDB documents. The module is actually incredibly simple, it makes
no attempt to integrate with the Play ORM frameworks because they are
really not a good match for working with a document database. All the
module does is provide a simple way to configure how to connect to
MongoDB, and get a JacksonDBCollection, configured ready to use with
Scala or Java objects, and managed by the Play application, it's up to
the user to decide how they want to use this.

The project can be found here:

https://github.com/vznet/play-mongo-jackson-mapper

and I've just released and deployed version 1.0.0-rc.1 to sonatype,
which within an hour or two should be synced to the central maven
repository.

I've only been using play 2.0 this week, and there's no documentation
anywhere about how to write a play 2.0 module, so everything I've done
I've worked out from reading the play 2.0 source code. If someone who
knows something wants to take a brief look over my plugin (it's only 1
file) to see if everything looks ok, I'd greatly appreciate it.

Ben McCann

unread,
Mar 16, 2012, 12:42:40 PM3/16/12
to play-fr...@googlegroups.com
Cool =)  Maybe add it to the list of Play 2 modules?

Thibault Lacroux

unread,
Mar 16, 2012, 2:27:35 PM3/16/12
to play-fr...@googlegroups.com
Great, I was waiting for it before move on Play2.

Pascal Voitot Dev

unread,
Mar 16, 2012, 5:06:51 PM3/16/12
to play-fr...@googlegroups.com
Don't worry about mongo support in Play2, I think there should be a lot of tools around it...

Pascal

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To view this discussion on the web visit https://groups.google.com/d/msg/play-framework/-/h_ny0XrNBewJ.

To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

Mark Waddle

unread,
Mar 17, 2012, 11:51:32 PM3/17/12
to play-fr...@googlegroups.com
Thanks jroper! I appreciate the simplicity of your module.

I am trying to set it up, and your instructions mention adding a line to build.sbt, although I don't have a build.sbt. I have a plugins.sbt? Do I need to download and compile the source some how? Today is my first day with 2.0, so you'll have to excuse me.

Thanks again for your contribution,
Mark


On Friday, March 16, 2012 4:32:38 AM UTC-7, jroper wrote:

jroper

unread,
Mar 18, 2012, 10:49:39 AM3/18/12
to play-framework
Hi Mark,

You can add it to your app dependencies in Build.scala, see
documentation here:

http://www.playframework.org/documentation/2.0/SBTDependencies

Cheers,

James

George Ward

unread,
Mar 20, 2012, 4:11:52 PM3/20/12
to play-fr...@googlegroups.com
Great work on geting the mongodb module out so fast, but there's a memory leak. You create a ConcurrentHashMap to store the elements but there is no eviction policy to remove these elements once they have been added. Therefore, if i left my web app running for two-three weeks  - I would have two-three weeks worth of data sitting on my java-heap, which is not ideal. May I suggest you use ehcache, play's caching, or a weak referenced map.

jroper

unread,
Mar 21, 2012, 5:36:15 AM3/21/12
to play-framework
Hi George,

I think you've missed the purpose of that cache. It doesn't store any
data, it stores references to JacksonDBCollections, which is
conceptually equivalent to a database connection to a particular
collection (table in the RDMS world), which in turn holds Jackson
object mappers that hold all the serialisation/deserialisation
configuration from classes that are being mapped to/from JSON, which
is very expensive to calculate because it requires a lot of
reflection, hence the need to cache it. If an application uses 10
different MongoDB collections, then there will only ever be 10
elements in that hash map. If an application is using enough
collections for this to be considered a memory leak and require
eviction, then the application is probably using MongoDB wrong.

Cheers,

James

George Ward

unread,
Mar 21, 2012, 3:11:42 PM3/21/12
to play-fr...@googlegroups.com
Hi James,

Thanks for the reply! What you are doing make sense, thanks for the clarification.

George

Daniel Berndt

unread,
Mar 22, 2012, 9:15:21 AM3/22/12
to play-fr...@googlegroups.com
To prevent others from having similar issues with including this module to the Build.scala, here is what my code looks like:

[...]
    val appDependencies = Seq( 
"net.vz.mongodb.jackson" %% "play-mongo-jackson-mapper" % "1.0.0-rc.2"
    val main = PlayProject(appName, appVersion, appDependencies, mainLang = JAVA).settings(
        resolvers += "Sonatype repository" at "https://oss.sonatype.org/content/repositories/releases/"
    )
[...]

this probably should also be included in the documentation.

Cheers,
Daniel

sas

unread,
Mar 24, 2012, 4:12:44 PM3/24/12
to play-framework
Hi

I'm trying to use this module

but I get this error:

com.mongodb.MongoException$Network: can't call something : ubuntu/
127.0.1.1:27017/hackaton

Reading the code I realized I had to enter my credentials con the
application.conf file like this:

mongodb.credentials="user:pass"

--

I've just realized that it was trying to connec to 127.0.1.1 instead
of 127.0.0.1

I changed my conf from

mongodb.servers="localhost:27017"
to
mongodb.servers="127.0.0.1:27017"

any idea was it was interpreting localhost as 127.0.1.1???

saludos

sas

Mark Waddle

unread,
Mar 25, 2012, 2:58:33 AM3/25/12
to play-fr...@googlegroups.com
The module defaults to the host name of "localhost", so maybe your /etc/hosts file is incorrect?

sas

unread,
Mar 25, 2012, 6:26:23 PM3/25/12
to play-framework
oops, you are right, my etc/hosts was screwed up...

thanks a lot mark

On 25 mar, 03:58, Mark Waddle <m...@redfoleo.com> wrote:
> The module defaults to the host name of "localhost", so maybe your
> /etc/hosts file is incorrect?
>
>
>
>
>
>
>
> On Saturday, March 24, 2012 1:12:44 PM UTC-7, sas wrote:
>
> > Hi
>
> > I'm trying to use this module
>
> > but I get this error:
>
> > com.mongodb.MongoException$​Network: can't call something : ubuntu/
> > 127.0.1.1:27017/hackaton
>
> > Reading the code I realized I had to enter my credentials con the
> > application.conf file like this:
>
> > mongodb.credentials="user:​pass"
>
> > --
>
> > I've just realized that it was trying to connec to 127.0.1.1 instead
> > of 127.0.0.1
>
> > I changed my conf from
>
> > mongodb.servers="localhost:​27017"
> > to
> > mongodb.servers="127.0.0.1:​27017 <http://127.0.0.1:27017>"
>
> > any idea was it was interpreting localhost as 127.0.1.1???
>
> > saludos
>
> > sas
>
> > On 22 mar, 10:15, Daniel Berndt <daniel.ber...@googlemail.com> wrote:
> > > To prevent others from having similar issues with including this module
> > to
> > > the Build.scala, here is what my code looks like:
>
> > > [...]
> > >     val appDependencies = Seq(
> > > "net.vz.mongodb.jackson" %% "play-mongo-jackson-mapper" % "1.0.0-rc.2"
> > > )
> > >     val main = PlayProject(appName, appVersion, appDependencies,
> > mainLang =
> > > JAVA).settings(
> > >         resolvers += "Sonatype repository" at
> > > "https://oss.sonatype.org/​content/repositories/releases/<https://oss.sonatype.org/content/repositories/releases/>​"
>
> > >     )
> > > [...]
>
> > > this probably should also be included in the documentation.
>
> > > Cheers,
> > > Daniel
>
> > > On Friday, 16 March 2012 12:32:38 UTC+1, jroper wrote:
>
> > > > I'm pleased to announce a new MongoDB module for Play 2.0.  This
> > > > module uses the mongo-jackson-mapper:
>
> > > >http://vznet.github.com/​mongo-jackson-mapper<http://vznet.github.com/mongo-jackson-mapper>
>
> > > > which uses Jackson annotations to map Java/Scala objects to/from
> > > > MongoDB documents.  The module is actually incredibly simple, it makes
> > > > no attempt to integrate with the Play ORM frameworks because they are
> > > > really not a good match for working with a document database.  All the
> > > > module does is provide a simple way to configure how to connect to
> > > > MongoDB, and get a JacksonDBCollection, configured ready to use with
> > > > Scala or Java objects, and managed by the Play application, it's up to
> > > > the user to decide how they want to use this.
>
> > > > The project can be found here:
>
> > > >https://github.com/vznet/​play-mongo-jackson-mapper<https://github.com/vznet/play-mongo-jackson-mapper>

Balamanikandan Thirugnanasambanthamoorthy

unread,
Apr 3, 2012, 12:13:24 AM4/3/12
to play-framework
Hai!

mongodb.host = "127.0.0.1"
mongodb.port = 27017

It is working form me
:) bye

James Roper

unread,
Apr 3, 2012, 5:48:30 AM4/3/12
to play-fr...@googlegroups.com
I'm glad it's working, but mongodb.host and mongodb.port are not read by the Play Mongo Jackson Module.  localhost:27017 is the default configuration, so the below would appear to work, but if you change the configuration below, it won't work.  What will work is:

mongdb.servers="127.0.0.1:27017"

Alexandre Bedritski

unread,
Apr 3, 2012, 5:01:32 PM4/3/12
to play-fr...@googlegroups.com

Hello, i updated my dependencies, imported all the libraries you mentioned in your BlogPost example on github,
but @objectId annotation is still undefined, i have some errors like this one

[error] /home/alex/work/scala/todo/app/models/Task.scala:14: not found: type ObjectId
[error] class Task(@ObjectId @Id val id: String,

What I'm trying to do is to replace the Anorm database with MongoDb in this example (the todo application) from the main site of playframework, but it's harder than I thought.

But for the instance, how to resolve this error with ObjectId?

Mark Hunter

unread,
Apr 4, 2012, 2:25:32 PM4/4/12
to play-fr...@googlegroups.com
Alexandre,

I've tried this and found the following code works for me:

  import org.codehaus.jackson.annotate.JsonProperty
  import reflect.BeanProperty
  import net.vz.mongodb.jackson.ObjectId

  case class Task(@ObjectId @Id id: Long, 
                @BeanProperty @JsonProperty("label") label: String)

Mark

Mark Hunter

unread,
Apr 4, 2012, 2:27:20 PM4/4/12
to play-fr...@googlegroups.com
Sorry that should have been:

  import org.codehaus.jackson.annotate.JsonProperty
  import reflect.BeanProperty 
  import net.vz.mongodb.jackson.ObjectId 
  case class Task(@ObjectId @Id id: String, 
                @BeanProperty @JsonProperty("label") label: String) 

On Wednesday, April 4, 2012 7:25:32 PM UTC+1, Mark Hunter wrote:
Alexandre,

I've tried this and found the following code works for me:

  import org.codehaus.jackson.annotate.JsonProperty
  import reflect.BeanProperty
  import net.vz.mongodb.jackson.ObjectId

  case class Task(@ObjectId @Id id: String, 

Alexandre Bedritski

unread,
Apr 4, 2012, 2:40:16 PM4/4/12
to play-fr...@googlegroups.com

Thanks for your reply,

I think this is because of my ide, that screwed things up. I spent another couple of hours on this problem and moved on to the salat extention, that i managed to get work after another 5 hours of fails. But now it works like a charm.

Btw what are the key differences between this extension and Salat-mongodb? Afaik this one uses jackson processor and salat saves tipe-hinting with the object in the database, anything else?

James Roper

unread,
Apr 5, 2012, 4:01:11 AM4/5/12
to play-fr...@googlegroups.com
I'm the author of the Mongo Jackson Mapper, and haven't used Salat, so some things I say here might be wrong about Salat.  But after skimming over Salat in 4 minutes, here's some key differences:

* Salat is targetted at Scala only, and so provides a more idiomatic Scala interface.
* Mongo Jackson Mapper uses Jackson to achieve much better deserialisation performance.  The binary BSON stream from MongoDB is parsed directly by Jackson and deserialised directly into Objects, whereas Salat takes the DBObject Maps that have been deserialised by the Java driver and converts them to objects, so you have an intermediate format that takes time to transfer between, and produces more garbage.  Additionally, Jackson is arguably the fastest databinder on the JVM, so even when the mapper is running in DBObject deserialisation mode (ie, it lets the Java driver deserialise the objects first, and then maps from the DBObjects like Salat does), it is probably still faster.
* Jackson is very mature and flexible, supporting many features including polymorphic deserialisation, views and very simple and powerful custom serialisers/deserialisers.  Salat in contrast requires you to write your objects in the format it expects (eg, it only supports case classes).  This may be fine for you, and does lead to simpler data object implementations, or maybe you want the flexibility of Jackson.

There are many other distinguishing features, but these seem to be the main ones to me.  I wouldn't say that one is better than the other, it all depends on your needs.

Cheers,

James

Alexandre Bedritski

unread,
Apr 5, 2012, 5:47:29 AM4/5/12
to play-fr...@googlegroups.com

Thank you for this comparison,


> Salat in contrast requires you to write your objects in the format it expects (eg, it only supports case classes).

Afaik there is some flexebility with annotations (like @Key or @Ignore here) but case classes are the only way to go, yes.

The example in your wiki is very limited and if you want to help new users of Play 2.0 Scala framework,
you might consider to put in your wiki the update of the "first application"
that those user are creating (a simple todo application from  the official documentation here, it is using in-memory
Sql database Anorm) by transmiting it to MongoDb support using your Mapper.

I didn't succeed in this task and there is nothing in the internets that could help me for the moment.

But I did the same thing for the Salat  and put it on github here

Thanks and best regards,

Alexandre.

Mark Hunter

unread,
Apr 5, 2012, 5:51:15 AM4/5/12
to play-fr...@googlegroups.com
+1 to that, great idea Alexandre.

An Ly

unread,
Apr 5, 2012, 9:20:04 PM4/5/12
to play-fr...@googlegroups.com
How to use DBRef (in Scala)? Sorry but i'm scala beginner :)

George Ward

unread,
Apr 7, 2012, 11:51:39 AM4/7/12
to play-fr...@googlegroups.com
Just a Fyi. Salat does support polymorphic objects through type hints - just like Jackson JSON. 
 
In fact, I found Salat to be more reliable than Jackson because it doesn't suffer from the compile bug https://issues.scala-lang.org/browse/SI-5165

Alex Jarvis

unread,
Jun 7, 2012, 12:47:05 PM6/7/12
to play-fr...@googlegroups.com
Hi, I've just spent a while playing with this lovely module, but wonder where is best to get the collection using MongoDB.getCollection ? I'm just asking because I've placed it inside a private static member inside the domain object and was wondering if this could have any unwanted side effects? What is the expected use (I'm using Java)?

For example:

public class BlogPost {
private static JacksonDBCollection<BlogPost, String> coll = MongoDB.getCollection("post", BlogPost.class, String.class);
@Id
public String id;
public String title;
public String body;
public WriteResult<BlogPost, String> save() {
return coll.save(this);
}
}

James Roper

unread,
Jun 11, 2012, 9:34:07 AM6/11/12
to play-fr...@googlegroups.com
Hi Alex,

I just happened to notice this question, in future please ask questions about the mongo jackson mapper play module here and it will ensure that I see it:


I need to do more testing, but this is probably not the best idea.  When the application reloads, the MongoDB connection will be closed, and your collection reference will be stale.  However, depending on how play application loading works, maybe it's ok, if the classloader is also reloaded each time on application start, then you won't have this problem.  Unfortunately I've never got a clear explanation from anyone about how play application loading/reloading works.  There's also potentially a race condition, if your class is loaded before the MongoDB plugin is started, that's going to cause issues.

My advice would be to use:

private static JacksonDBCollection<BlogPost, String> coll() {
   return MongoDB.getCollection("post", BlogPost.class, String.class);
}

The lookup will be no more than a hash map lookup on each access of the collection, which is very fast (especially compared to the amount of time it will take to actually perform the MongoDB operation/query you're about to make), and it solves all of the problems I mentioned.

Cheers,

James

Alex Jarvis

unread,
Jun 22, 2012, 5:41:19 AM6/22/12
to play-fr...@googlegroups.com
Hi James,

Sorry it's taken me a while to reply to you, but thank you for your answer, it's really helpful and I've updated my code with your change :)

Cheers,
Alex

Alexandre Bedritski

unread,
Aug 1, 2012, 7:08:21 AM8/1/12
to play-fr...@googlegroups.com
Hi, Raphael,

here is a "quick start" tutorial for Java Play framework application:

https://github.com/Mironor/Play-2.0-Java-MongoDb-Jackson-exemple

It is based on the todo application from the official manual, so be sure to complete it first (or grab the files from the corresponding commit from the link above).

Best,

Alexandre

Michael Schroeder

unread,
Feb 27, 2014, 10:42:04 AM2/27/14
to play-fr...@googlegroups.com
Hello Alexandre,

THANKS A BUNCH! Just want to thank you for your contribution with this little example code. I had a big win developing a Play 1 app backed with mongodb and play-morphia, so, I didn't think twice about committing to a new fast paced project on Play 2. Then reality set in, as I began to piece together the app. Wholly crap, Play 2 was a ground up rebuild.. they should have called it "Work" instead of "Play". 

I struggled to get productive with the morphia plugin, and tracking changes with the massively evolving play 2 framework, was frustrating. I blew two weeks getting up to speed with 1x 2x changes. Searching for solutions to issues with the entirely inconsistent google groups / stackoverflow [play 1, 2, 1.x 2.x.. ] craziness led to me almost blowing-off Play. I stumbled into the Jackson mongo mapper and your little bit of example code, and had it running in one minute. 

I'm not sure how everyone else feels, but having working examples is essential for me. 

Cheers!

Michael

Bikramjit Singh

unread,
Jun 9, 2014, 2:43:39 AM6/9/14
to play-fr...@googlegroups.com
Hi James,

Is there a way I can choose db name on runtime rather than defining it in application.src?

ch. rehan Sarwar

unread,
Jun 13, 2015, 1:17:14 AM6/13/15
to play-fr...@googlegroups.com
i did'nt understand how to add the jackson mapper in play framework can you send me the detail link description?

ch. rehan Sarwar

unread,
Jun 13, 2015, 1:20:36 AM6/13/15
to play-fr...@googlegroups.com
how to add mongo module in play 2.0 for java

On Friday, March 16, 2012 at 2:06:51 PM UTC-7, Pascal wrote:
Don't worry about mongo support in Play2, I think there should be a lot of tools around it...

Pascal

On Fri, Mar 16, 2012 at 7:27 PM, Thibault Lacroux <ryk...@gmail.com> wrote:
Great, I was waiting for it before move on Play2.


Le vendredi 16 mars 2012 12:32:38 UTC+1, jroper a écrit :
I'm pleased to announce a new MongoDB module for Play 2.0.  This
module uses the mongo-jackson-mapper:

http://vznet.github.com/mongo-jackson-mapper

which uses Jackson annotations to map Java/Scala objects to/from
MongoDB documents.  The module is actually incredibly simple, it makes
no attempt to integrate with the Play ORM frameworks because they are
really not a good match for working with a document database.  All the
module does is provide a simple way to configure how to connect to
MongoDB, and get a JacksonDBCollection, configured ready to use with
Scala or Java objects, and managed by the Play application, it's up to
the user to decide how they want to use this.

The project can be found here:

https://github.com/vznet/play-mongo-jackson-mapper

and I've just released and deployed version 1.0.0-rc.1 to sonatype,
which within an hour or two should be synced to the central maven
repository.

I've only been using play 2.0 this week, and there's no documentation
anywhere about how to write a play 2.0 module, so everything I've done
I've worked out from reading the play 2.0 source code.  If someone who
knows something wants to take a brief look over my plugin (it's only 1
file) to see if everything looks ok, I'd greatly appreciate it.

--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To view this discussion on the web visit https://groups.google.com/d/msg/play-framework/-/h_ny0XrNBewJ.

To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.

Aliaksandr Bedrytski

unread,
Jun 17, 2015, 3:58:10 PM6/17/15
to play-fr...@googlegroups.com
You mean play 2.0 or play 2.4? If it's play 2.0, you may find an example here https://github.com/Mironor/Play-2.0-Java-MongoDb-Jackson-exemple 

But if it's 2.4, play-mongo-jackson-mapper library wasn't updated for 2 years and does not support the dependency injection in 2.4 throwing this error:$

Could not find a suitable constructor in play.modules.mongodb.jackson.MongoDBPlugin. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. at play.modules.mongodb.jackson.MongoDBPlugin.class(MongoDB.scala:163) while locating play.modules.mongodb.jackson.MongoDBPlugin

You received this message because you are subscribed to a topic in the Google Groups "play-framework" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/play-framework/K7IrXyXvL8w/unsubscribe.
To unsubscribe from this group and all its topics, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/f43db62d-1a96-4524-bcbb-93edd2cef21e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Roshan Kumar

unread,
Jun 3, 2016, 7:31:10 AM6/3/16
to play-framework

Hi James 

I have developed a demo ODM that use java async driver .

https://github.com/raimdtu/PlayAsyncJavaMongoODM

It will give you overview.

It has some initial work .

Reply all
Reply to author
Forward
0 new messages