Yair's Tweaks & Tricks

Mainly software


2 Comments

Intellij Tips

As I am using Intellij for my daily software development work, I thought I’d share some useful tips.

Tip #1 – SCM Shortcut

quick access to SCM (Source Control commands) – Alt + `

 

Tip #2 – Branch management

If you want to hold multiple modules in the same project that have the same maven artifact id – you don’t have to open a new project.

Make sure the branch modules have a unique fie system folder name. I.e. module ‘foo’ is in ‘foo’ folder in trunk, but in branch the folder name is ‘foo-branch’. In this case you can import the branch module and have it side by side with the trunk module.

Note: you may want to update the ‘name’ in the pom.xml so you can easily distinguish between trunk and branch modules in the ‘Maven Project’ tab.

 

Tip #3 – module grouping

In case you want to group some modules together (very useful when managing trunk and branch together) you can right click on a module and choose ‘Move module to group’.

 

Tip#4 – Setting Module Dir as default working directory

Go to ‘edit configurations’ and under defaults define ‘$MODULE_DIR$’ as the working directory:

intellij default configurations

Naturally repeat this for Junit and and any other run type you wish.

 

Tip#5 – Dependencies Tree

Although dependencies graph exist only in the commercial edition you don’t really need them. You can see the full tree in the ‘Maven Project’ tab. If you want to understand how the maven resolution was done and why (maybe) you see the “wrong” version – you should install the “Maven Helper” plugin (just search for it the plugin repositories within Intellij) that will add another tab when you open your pom.xml file and you will see which version was omitted because of conflict (similar to the maven plugin supported in Eclipse).
Thanks to Izek Greenfield for this tip.

 

Tip #6 – Expand Tree Node

Know those times you need to expand all but only under the context you are currently focused (i.e. in ‘Maven Project’ expand all dependencies)?

Well, Ctrl + ‘+’ expands the whole tree and not only the specific node. BUT – use the numpad ‘*’ and there you have it. 🙂


2 Comments

Spring Data and Scala – can they Mix?

A while back I got to the task of creating my first fully blown Scala server. I had a few decisions to make:

  1. Persistence Store
  2. Persistence Framework
  3. Application Server

I’ve had my eye set a long time on Mongo – so that was an easy choice.

Using NoSql basically removed any JPO related frameworks from the table (which i consider to be a good thing). Loving Spring as I do, led me to choose spring-data as the persistence framework. It seemed to have decent support for mongo.

For the Application Server I’ve decided to rely on past successes and used Jetty 9.

Setting up mongo was rather easy. As I was using Scala, I wanted to use case classes as my model. The goal was to use the same objects for my REST layer using Jackson Scala Module on one hand and be able to write the same Object type in my persistence store.

Spring-data looked promising at first. I was able to send Json in, convert to my object model transparently using the following xml snippet:

<mvc:annotation-driven>
<mvc:message-converters>
<beanclass="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="mapper"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

The mapper was an instance of jackson-module-scala. So far so good.

I did notice one odd thing. Spring didn’t know how to serialize my case classes out-of-the-box (obviously), so it used a generic class serializer when writing my objects into Mongo. this worked nicely enough reading back the state into an object until I hit a show stopper.

Apparently, case classes that contained a Scala ‘Option’ – were not de-serialized properly. For example, consider the following code:

myOptionField match {
case Some(value) => do something
case None => do something else
}

Turns out, it never got to the ‘case None’ segment. Reading my state from Mongo, although serialized as None, caused the above to break. The only workaround was to do something like this:

myOptionField match {
case Some(value) => do something
case _=> do something else
}

This, of course, was less than optimum.

If that wasn’t enough, for some cases where we had to successive Scala Option fields – we got weird Json serialization errors:

com.fasterxml.jackson.databind.JsonMappingException: (None,None) (of class scala.Tuple2)

Hmmm. I Don’t feel comfortable with the current state…

As my project was young, I had the luck to be able to re-factor. Luckily I had an isolated db-layer which enabled me rather easily to revisit my Persistence Framework decision.

Reading some more, I’ve found that Mongo has an official Scala driver (how on earth did I miss that?). Nice. But wait. Starting to implement the change from spring-data to casbah scala driver quickly revealed I can’t pass my case classes to the scala driver. It only uses MongoDB Objects. Oh man. Do I really have to create readers and writers to all my 20+ case classes?

Well, NO.

Salat to the rescue. Finally a neat solution. I can easily convert my case classes to and from mongo using concise and easy to read code:

val mongodbConnetion = MongoConnection(host,port)
val mydb = mongodbConnetion("mydb")
mydb.writeConcern = WriteConcern.FsyncSafe
val my-coll-db = mydb("my-coll-db")

//insert new document
my-coll-db.insert(grater[MyCaseClassObject].asDBObject(myObj))

That’s it. Easy to use. Easy to read. Easy to write.

To summarize, spring-data (great as it is) isn’t the best fit to work with Scala. Luckily we have good alternatives.