Typesafe Activator

Reactive App generated with EasyMda

Reactive App generated with EasyMda

June 5, 2014
reactive akka spray slick scala

Demo Reactive application completely generated with EasyMda

How to get "Reactive App generated with EasyMda" on your computer

There are several ways to get this template.

Option 1: Choose reactive-gen-easymda in the Typesafe Activator UI.

Already have Typesafe Activator (get it here)? Launch the UI then search for reactive-gen-easymda in the list of templates.

Option 2: Download the reactive-gen-easymda project as a zip archive

If you haven't installed Activator, you can get the code by downloading the template bundle for reactive-gen-easymda.

  1. Download the Template Bundle for "Reactive App generated with EasyMda"
  2. Extract the downloaded zip file to your system
  3. The bundle includes a small bootstrap script that can start Activator. To start Typesafe Activator's UI:

    In your File Explorer, navigate into the directory that the template was extracted to, right-click on the file named "activator.bat", then select "Open", and if prompted with a warning, click to continue:

    Or from a command line:

     C:\Users\typesafe\reactive-gen-easymda> activator ui 
    This will start Typesafe Activator and open this template in your browser.

Option 3: Create a reactive-gen-easymda project from the command line

If you have Typesafe Activator, use its command line mode to create a new project from this template. Type activator new PROJECTNAME reactive-gen-easymda on the command line.

Option 4: View the template source

The creator of this template maintains it at https://github.com/robinbakkerus/reactive-gen-easymda#master.

Option 5: Preview the tutorial below

We've included the text of this template's tutorial below, but it may work better if you view it inside Activator on your computer. Activator tutorials are often designed to be interactive.

Preview the tutorial


This Activator Template is a yet another Reactive application based on: Spray, Akka and Slick with a few twists!

  • In the Slick persistence layer, a (almost) complete, very efficient (meaning: with a little as possible sql statements), ORM is implementen. Currently this version supports most standard types, onetomany manytoone and onetoone relations.
  • But most important ... the entire application is completely generated, with an Eclipse plugin. Not a single line of code was hand-coded!
This so called EasyMda plugin is currently still work in progess, hence this Activator only demonstrates the generated Scala based backend, but in the near future it can also generate a fully functional Google Dart frontend.
By than, I also want to have the currently missing ORM pieces: manytomany relations (resulting in a join-table), object inheritance and support for blob and clob datatypes.
Please visit: the Easymda website for more information how this code generator works. There you may find tutorials, some Youtube video's, and documentation that shows how easy it is to modify the (jet-engine) templates, so that you can modify the generated code anyway you want.

Please let me know what parts of the code can be improved, so that I can update the corresponding template(s)

The Reactive App

This demo application is a typical Reactive based on the well known stack: Spray, Akka and Slick. I created the cartridge templates based on numerous examples from previous activator projects.

What is being generated


In src/main/resources/models-sources.zip you can find all the java-based model, that were used to generate this reactive application.
For all the entities (all classes that implements IEntityType), the following classes are generated (using the model class Tsta as an example): For other model classes, like services (model class that implement IServiceType) or dto's (implement IDtoType) somewhat similar classes are generated, but without the dao layer.

Persistence layer, with Slick

Most of the time was spent in the ability to support complete ORM mapping, similar to Hibernate but than better. It is now indeed possible to retrieve with one service call a complete (deeply) nested object tree, and also perform a full update of an object tree. I try to this in such a way that it requires a little as possible sql calls. And I also want to have full control over what exactly is fetched.

For this reason, all entity classes have two (maybe cryptic) val properties: fd:Option[FdXxx], ohc:List[Long] The "fd" is a shortcut for FetchDepth. This option can be used to tell exactly what nested relations should be fetched or not. So rather than the @Eager vs @Lazy annotation that is set only once, this option gives the client control over this behaviour. By default the generated find command will not fetch any nested object, and the generated retrieve will fetch the complete tree, but the client this is free to change this in any way it wants.

The "ohc" is a shortcut for OldHashCode(s). This value is set when an object is retrieved, and it contains the hashcode of the corresponding row class, so it will be returned to the client. When the client later updates this object, with the saveXxx service call, the dao layer will compare the old hashcode with the new hashcode and will only perform an actual sql update if the hashcodes differ. And it does so for all nested objects. You may have noticed that the "ohc" is a List. That is because in addition to the 'main' hashcode, that is the hashcode of the corresponding row class, it may also contain hashcode(s) for all manytoone relations. These values are used to figure out a the client added and/or removed an element from a manytoone collection. For retrieving an object tree different strategies can be used. One is to generate a (possible very complex) join query. This is difficult to generate and may result in transporting a lot of waste because many same column values will be transferred for each collection instance again. A naive strategy is to reuse the retrieve commands of the nested objects. This is elegant and easy to generate but this may result in many individual sql select calls. I opted for another strategy. I try to execute just one sql statement for each nested class in the object tree, and merge the results afterwards. These sql statements for each class can run parallel (this is not done yet, see improvements), so that the performance is in par with a complex join query, maybe faster because (much) less data needs to be transferred.

comments powered by Disqus