Re: Scala ORM: Activate & MapperDao

647 views
Skip to first unread message

Jacobus

unread,
Nov 7, 2012, 1:22:25 AM11/7/12
to scala...@googlegroups.com, fwbr...@gmail.com
Hi Kostas and Flávio,

I had a quick look at both your libraries, and they both look pretty amazing. Would be great if you could join forces in some way or another.

Some ideas:
- It would be nice if your libraries could support composition (see below) in some way or another
- Put a logo of one or two companies that use your products on your home pages. It creates confidence knowing that something is used in production.

Here's an example from a Slick presentation (http://slick.typesafe.com/docs/) relating to composition:

def personByAge( from:Int, to:Int ) =
Persons.filter( p => p.age >= from && p.age <= to )

// Interests of people between 20 and 25
for( p <- personByAge(20, 25); i <- Interests; if i.personId === p.id) yield i.text

// Cars of people between 55 and 65
for( p <- personByAge(55, 65); c <- Cars; if c.personId === p.id) yield c.model

I'm not saying your libraries should look like this. I'm just saying it is great for any toolset to allow a developer to break a problem into smaller pieces and then compose bigger solutions. Your libraries probably already do this in some other way, but I could not find it.

I'm off, cheers,
Jacobus

Konstantinos Kougios

unread,
Nov 7, 2012, 6:44:01 AM11/7/12
to scala...@googlegroups.com
Hi Jacobus,

With mapperdao you can do the same like:

---------
class Person(age:Int,interests:List[Interest],cars:Set[Car])

val pe=PersonEntity
def personByAge( from:Int, to:Int ) = (select from pe where pe.age>=from
and pe.age<=to).toList(queryDao)

personByAge(20,25).map(_.interests.text).flatten
personByAge(55,65).map(_.car.model).flatten
---------

MapperDao been an ORM doesn't work with id's (but you could as well do
that if you want). So in my examples above I assume a domain model that
doesn't care about database id's.

Also mapperdao assumes some sort of layers in an application i.e. if this

for( p <- personByAge(20, 25); i <- Interests; if i.personId === p.id)
yield i.text

is on the controller layer (instead of mvc), then effectively the code
does queries in the controller layer which is not the best thing to do
in a project. MapperDao has the utility mixins to support ease of dao
layer creation as all dao ops should belong to that layer so that it is
easy to maintain a large codebase and resolve data related issues.

Cheers

Flávio W. Brasil

unread,
Nov 9, 2012, 6:02:56 AM11/9/12
to Jacobus, scala...@googlegroups.com
Hello Jacobus,

Thanks for the suggestions. I personally prefer to have a sql-like DSL than to use "pseudo" collections. Sql is much more expressive to deal with data queries.

-- 
Flávio W. Brasil
{persistence as it should be}

Flávio W. Brasil

unread,
Nov 9, 2012, 6:12:50 AM11/9/12
to Kostas kougios, Tim Pigden, scala...@googlegroups.com
Hello Kostas and Tim,

Example on why Mapperdao has a veiled mutability:


-- 
Flávio W. Brasil
{persistence as it should be}

On Tuesday, 6 de November de 2012 at 20:32, Kostas kougios wrote:

Ok, to continue the discussion in this separate thread from https://groups.google.com/forum/?fromgroups=#!topic/scala-user/TNG6KG0y2F8

...


Tim Pigden

unread,
Nov 9, 2012, 6:29:43 AM11/9/12
to Flávio W. Brasil, Kostas kougios, scala-user
ah - but for me it's important that "website" is an immutable object and a case class. In that case would I not have to implement a secondary layer on top and we've conceptually just moved the problem from the database | application interface into a activate | rest-of-application interface?

--
Tim Pigden
Optrak Distribution Software Limited
+44 (0)1992 517100
http://www.linkedin.com/in/timpigden
http://optrak.com
Optrak Distribution Software Ltd is a limited company registered in England and Wales.
Company Registration No. 2327613 Registered Offices: Orland House, Mead Lane, Hertford, SG13 7AT England 
This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Optrak Distribution Software Ltd. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error.

Flávio W. Brasil

unread,
Nov 9, 2012, 6:53:39 AM11/9/12
to Tim Pigden, Kostas kougios, scala-user
Ok, and for me is important to have a safe persistence layer.
So, let's consider this as a question of preference. :)

-- 
Flávio W. Brasil
{persistence as it should be}

Konstantinos Kougios

unread,
Nov 9, 2012, 7:10:39 AM11/9/12
to "Flávio W. Brasil", Tim Pigden, scala-user
Flavio, thanks for the sample code. I'll have a better look later on but from a quick look I had, here is the question:

how does activate solve this issue when you have multiple application servers accessing 1 database (or a set of them) ?

Flávio W. Brasil

unread,
Nov 9, 2012, 7:33:13 AM11/9/12
to Konstantinos Kougios, Tim Pigden, scala-user
The 1.1 version has a mechanism to coordinate multiple VMs as a distributed STM acessing one database. 
Take a look in this spec, it's the same heavy concurrent modification scenario but using multiple VMs, each one with multiple threads:


Obs.: The test uses the great gfork framework to create multiple VMs.

-- 
Flávio W. Brasil
{persistence as it should be}

Konstantinos Kougios

unread,
Nov 10, 2012, 7:31:36 AM11/10/12
to "Flávio W. Brasil", Tim Pigden, scala...@googlegroups.com
Hi Flavio,

    I couldn't compile the project, I am not very familiarized with sbt and it always gives me a weird error that I can't do much about it. This time it couldn't find an artifact:

com.typesafe.sbteclipse#sbteclipse-plugin;2.1.0-M2: not found

Anyway, here are my thoughs:

1.    I think you put too much emphasis on STM where as you are coding an ORM library. An API "should carry it's weight", and mapperdao as an ORM library does carry it's weight and only that. MapperDao does ORM, not STM. That has the benefit that someone who don't want to use STM (most of the cases) can use mapperdao, but also anyone who wants to use STM can use mapperdao and on top of that add his preferred STM to achieve what activate achieves.

I am a bit unclear on what would happen if activate client code is like:

----
var website
transactional {
      website = new Website("http://activate-framework.org", counter)
}

website.url="something else"
---

Is the modified url still reflected in the database and in all mutable instance inside the JVM? If not then there is a significant flaw of the approach as it allows hard to find bugs. Mutability is a big .. bugger! If activate currently allows this code then I would recommend if somehow magically activate was throwing an exception if someone tried to modify the url outside of the transaction.

------------------------------------------------------------------------------------------------------------------


2.    MapperDao and immutable classes is a major benefit to any client code. It seems to me that Activate entities have to be mutable:
class Website(var url: String, val counter: Counter)
    extends Entity

where as mapperdao entities can be immutable. Mutability is a source of lots of bugs and a maintenance nightmare for big projects. In my commercial experience so far we never used STM but we very often use immutable domain models.

------------------------------------------------------------------------------------------------------------------


3.    Regarding mapperdao's entities, yes indeed there is a bit more coding and are a bit more involved. In fact the extra code is the only drawback but there are a lot of benefits:

    a.    With mapper dao the domain class don't depend on the ORM library, i.e. the mapperdao entity looks like:

class Website(val id: Int, val url: String, val counter: Counter)

where as the activate entity depends on activate:

class Website(var url: String, val counter: Counter) extends Entity

    b.    customization of mappings ,i.e. fields that map to different column names, data conversion before storing/retrieval (i.e. convert enums to string or integers), sorting of loaded related data etc, I am going to do a quick demo:

    // immutable domain model, doesn't depend on the ORM library
    case class Product(name: String, attributes: List[Attribute]) // the non-persisted entity doesn't contain an id because the id is autogenerated by the database and available only for persisted entities
    case class Attribute(name: String, value: String)

...
    object ProductEntity extends Entity[Int, SurrogateIntId, Product] {
        val id = key("id") autogenerated (_.id) // the persisted entity retrieves the autogenerated id. All persisted entities are Product with SurrogateIntId
        val name = column("name") to (_.name.toLowerCase)  // assuming we would like to convert the name to lower case when stored in the database
        val attributes = manytomany(AttributeEntity) to (_.attributes) // here we map it as many to many but we could map it as one to many

        def constructor(implicit m) = new Product(id, name, m(attributes).toList.sortWith(_.name<_.name)) with SurrogateIntId // when we load the attributes, we want them to be sorted by name
    }

So as you see the mappings offer a great deal of flexibility. Now i.e. in order to do the toLowerCase in activate, we might have to (please correct me if I am wrong)

transaction {
    product.name=title.toLowerCase // this is visible to all instances within the jvm ???
}
product.name=title // restore the original value, is this visible to all instances within the jvm???

    c.    Avoiding annotations: an ORM that uses annotations within the domain classes not only couples the domain classes to the ORM tool but also ends up with ugly code. I.e. how many times our hibernate getters ended up having this:

@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinTable(name="Flight_Company",
        joinColumns = @JoinColumn(name="FLIGHT_ID"),
        inverseJoinColumns = @JoinColumn(name="COMP_ID")
    )
public X getX()...

So more lines of code for the ORM rather than properties or behavior!!! Sooner or later if an ORM needs to support client code it will end up like that. MapperDao embraces these needs instead of trying to hide them to "reduce" the number of lines. Also note that to read annotations you need reflection.

    d.    MapperDao queries IMHO are more natural than Activate ones, probably due to mapperdao's mappings. I.e. copying from activate sample project:

    // Queries
    // The query operators available are :==, <, :>, <=, >=, isNone, isSome, :||, :&&, like and matches.
    // Note that the queries can be made about abstract entities (abstract trait and class).
    // Perform queries within transactions
    transactional {
        val result = query {
            (person: Person) => where(person.name :== "John2") select (person)
        }
        for (person <- result)
            println(person.name)
    }

So why the ":>" operator instead of ">"? Why the ":||" or ":&&" ? MapperDao DSL had only to use "===" instead of "=="

The same query with mapperdao looks like a sql and hence a programmer doesn't have to learn anything new:

val pe=PersonEntity
(select from pe where pe.name === "John2").toList(queryDao)

the operators that you can use with mapperdao are === , > , < , <= , >= , and , or . Except the "===", the rest match a typical select SQL.

Also IMHO mapperdao DSL is more readable, i.e. compare:

activate:
query { (person: Person) => where(person.name :== "John2") select (person) }

mapperdao:
(select from pe where pe.name === "John2").toList(queryDao)

4.    does activate support more than 1 database? It seems "transactional" and "query" are static and "magically" get the database connection. MapperDao supports multiple databases. What if the WebSite entity was stored across multiple databases? Which value from which database does the JVM instance reflect?

5.    I still have to see how activate deals with auto-generated id's and also how many-to-many , one-to-many, many-to-one and one-to-one are mapped. I.e. when an entity contains a Set[X], is that a many to many or one to many?

6.    And how does activate deal with inheritance?

There is more functionality that mapperdao's model allows. I.e. you can map entities that don't live in a database (i.e. entities retrieved via a web service call or maybe legacy Hibernate entities). Also it supports entities with composite primary keys and so on. MapperDao follows the principle "do one thing and do it well" allowing client code to have an STM layer on top if they wish.

Kostas

Konstantinos Kougios

unread,
Nov 10, 2012, 7:33:17 AM11/10/12
to "Flávio W. Brasil", Tim Pigden, scala-user
are you sure that this is faster than managing the sync in the database/transaction level? What if you have 3 or 10 servers connecting with the same database?

Flávio W. Brasil

unread,
Nov 10, 2012, 9:10:44 AM11/10/12
to Konstantinos Kougios, Tim Pigden, scala-user
Yes, it's faster. Optimistic locking with efficient memory usage scales very well.

-- 
Flávio W. Brasil
{persistence as it should be}

Tim Pigden

unread,
Nov 10, 2012, 9:50:42 AM11/10/12
to Flávio W. Brasil, Konstantinos Kougios, scala-user
It's clear to me that the two approaches have divergent but not necessarily conflicting objectives.
We also have 3 different threads going on here:
1. brevity of expression of the model
2. brevity or elegance of the querying 
3. mutability
And I'd like to add one that Flavio didn't answer earlier - can I run my weird postgis queries in an Activate world?

Anyway #3 seems to be the critical differentiation.
mapperdao provides a mechanism to create immutable objects from the database and lets the mutability reside solely at the database level. 
STM (as I understand it) is a mechanism for ensuring that state of mutable objects is held in common and persisted automatically to the database.
One of the main motivations behind scala is to allow the fusion of functional programming techniques with objects - and one of the main things about functional programming style is use of immutable objects to enhance "reasoning about correctness" or, to you and me, "reduce bugs".

Now I don't know how Konstantin uses mapperdao, but as far as I'm concerned the domain model needs to immutable where all the business logic is going on and eventually it needs to end up in a mutable store (aka the database) because - well that's because mutable databases are about all we've got at the moment.

As far as I'm concerned activate is therefore moving the boundary of the mutable world out of the database and into memory. Even from my point of view, this is not necessarily a bad thing. If I have a high volume of data transfers to the database (I don't at the moment, but here's hoping ..) STM and various clustering mechanisms and optimistic locking  etc are all potentially strong benefits - so I could be thinking of an immutable layer in front of what has become a highly structured database cache. But right now, a single database server is more than enough for my needs so STM is irrelevant to me.

On the other hand if I wasn't interested in immutable domain models then the reverse argument could be applied - STM allows me unfettered access to the underlying mutable database.

Is that a fair summation?

And if so, does that have consequences for the design of your respective libraries - and your intended roadmaps and the way you promote them? Since neither of you are doing this on a big company budget it would make sense focus on areas of respective strength rather than think of yourselves as in a general undifferentiated ORM arena.

Tim

Kostas Kougios

unread,
Nov 10, 2012, 1:18:59 PM11/10/12
to Tim Pigden, "Flávio W. Brasil", scala-user
In the end, what will matter, as pointed by Tim, is the adoption of mapperdao or activate by people and organisations. And thats where i believe both libraries might loose the game. Developers will go with the flow and use libraries that are adopted by companies (and hence it will be easier to use their skills at work) and companies will adopt tools that are backed by bigger organisations, i.e slick and typesafe. Stm, mutability etc wont matter as mapperdao or activate wont even be a candidate for big projects. 

But not all is lost! Hopefully mapperdao will have more code contributors and be part of a big open sour e house.

Indeed the discussion is an all around evaluation of both libraries. To summarise it, mapperdao can acquire an stm layer as a separate library (or projects can use their preferred stm on top of mapperdao) , so no loss there. And for any real life project, mappings and overriding of the convention is a certainty,  so mapperdao embraces that and all the benefits that come along with mappings in scala code.

I use mapperdao in a project related to the uk and eu retail sector with traffic reaching 800 requests per second per server. Mapperdao is now the main orm lib with the most important classes been loaded by mapperdao and some legacy hibernate code still in our way. Most of our domain model is java and scala immutable classes - for a good reason. Mutability was a big scaling up problem as we had to clone cached entities, had bugs due to mutable state and memory usage and gc times were pretty bad as we had also to keep those instances into user session. With mapperdao we have one instance of each unique object. Mapperdao also allowed interning of related entities. Quite a lot of improvements were introduced due to mapperdao and the flexibility of scala mappings.

Regarding postgis, i am thinking of adding an extra mapping method, where one can map a field to a function instead of a column. This way i.e. a postgis column could be converted to a string and vice versa. I dont know if that helps but it could definitely come handy, postgis or elsewhere and would be a nice addition to the lib.
Something like

Val coordinates=column("coordinates") readvia(readfunction) writevia(writefunction) to (_.coords)

Sent from my self, sorry for any typos

Kostas Kougios

unread,
Nov 10, 2012, 1:22:25 PM11/10/12
to "Flávio W. Brasil", Tim Pigden, scala-user
Assuming most of the updates update the same data, it might be. But what if updating the same data is rare? Wouldnt stm and sync between servers be an overhead as most of the time there wont be a conflict of the updates?

Sent from my self

Flávio W. Brasil

unread,
Nov 11, 2012, 8:10:26 PM11/11/12
to Konstantinos Kougios, Tim Pigden, scala...@googlegroups.com
Hello. 

    I couldn't compile the project, I am not very familiarized with sbt and it always gives me a weird error that I can't do much about it. This time it couldn't find an artifact:

com.typesafe.sbteclipse#sbteclipse-plugin;2.1.0-M2: not found
Remove the file project/plugins.sbt or find a repository/version for the plugin.

1.    I think you put too much emphasis on STM where as you are coding an ORM library. An API "should carry it's weight", and mapperdao as an ORM library does carry it's weight and only that. MapperDao does ORM, not STM. That has the benefit that someone who don't want to use STM (most of the cases) can use mapperdao,
Please name what is the weight that Activate carries. I see a lot of weight using Mapperdao. Why do you think that in the most cases people don't need a STM? The STM is just a better way to do an ORM, wich provides better consistency and scalability.

but also anyone who wants to use STM can use mapperdao and on top of that add his preferred STM to achieve what activate achieves.
Wrong! Is not that simple to put a STM on top of a simple ORM consistently. If it looks simple to you, please demonstrate.
I am a bit unclear on what would happen if activate client code is like:

----
var website 
transactional {
      website = new Website("http://activate-framework.org", counter)
}

website.url="something else"
---
The STM deals with transaction isolation e concurrent access for you, don't worry. 

Is the modified url still reflected in the database and in all mutable instance inside the JVM?
This is very basic question, please take a look in what is a STM. Activate adds durability on STM transaction commit time, "syncing" with the database.
 
If not then there is a significant flaw of the approach as it allows hard to find bugs. Mutability is a big .. bugger!
Wrong! Activate deals with mutability and concurrency in a perfectly safe way as can you see in the test. A veiled mutability like exists in Mapperdao is what looks buggy to me.
 
If activate currently allows this code then I would recommend if somehow magically activate was throwing an exception if someone tried to modify the url outside of the transaction.
Activate throws a RequiredTransactionException if you try to create or modify an entity without a transaction. Please do not make recommendations without read the documentation or use Activate.
2.    MapperDao and immutable classes is a major benefit to any client code. It seems to me that Activate entities have to be mutable:
class Website(var url: String, val counter: Counter)
    extends Entity

where as mapperdao entities can be immutable. Mutability is a source of lots of bugs and a maintenance nightmare for big projects. In my commercial experience so far we never used STM but we very often use immutable domain models.
Decouple the presentation layer is a hard problem. Having a fake immutable class representing a mutable shared state don't solves the problem and creates a bigger issue.

3.    Regarding mapperdao's entities, yes indeed there is a bit more coding and are a bit more involved. In fact the extra code is the only drawback but there are a lot of benefits:

    a.    With mapper dao the domain class don't depend on the ORM library, i.e. the mapperdao entity looks like:

class Website(val id: Int, val url: String, val counter: Counter)

where as the activate entity depends on activate:

class Website(var url: String, val counter: Counter) extends Entity
I don't see the benefit from Mapperdao separate entity declaration that justifies so many lines of code.

    b.    customization of mappings ,i.e. fields that map to different column names, data conversion before storing/retrieval (i.e. convert enums to string or integers), sorting of loaded related data etc, I am going to do a quick demo:

    // immutable domain model, doesn't depend on the ORM library
    case class Product(name: String, attributes: List[Attribute]) // the non-persisted entity doesn't contain an id because the id is autogenerated by the database and available only for persisted entities
    case class Attribute(name: String, value: String)

... 
    object ProductEntity extends Entity[Int, SurrogateIntId, Product] {
        val id = key("id") autogenerated (_.id) // the persisted entity retrieves the autogenerated id. All persisted entities are Product with SurrogateIntId
        val name = column("name") to (_.name.toLowerCase)  // assuming we would like to convert the name to lower case         when stored in the database
        val attributes = manytomany(AttributeEntity) to (_.attributes) // here we map it as many to many but we could map it as one to many

        def constructor(implicit m) = new Product(id, name, m(attributes).toList.sortWith(_.name<_.name)) with SurrogateIntId // when we load the attributes, we want them to be sorted by name
    }
You save an entity and it is persisted with another value using toLowerCase? Seems a very strange feature to me.

So as you see the mappings offer a great deal of flexibility. Now i.e. in order to do the toLowerCase in activate, we might have to (please correct me if I am wrong)
Yes, there isn't a magic value transformation when the entity is persisted. It's very simple feature to implement, but I don't see any benefit of getting it on Activate.

transaction {
    product.name=title.toLowerCase // this is visible to all instances within the jvm ???
}
product.name=title // restore the original value, is this visible to all instances within the jvm???
Like I said please study the STM approach to deal with concurrency and you will understand.

    c.    Avoiding annotations: an ORM that uses annotations within the domain classes not only couples the domain classes to the ORM tool but also ends up with ugly code. I.e. how many times our hibernate getters ended up having this:

@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    @JoinTable(name="Flight_Company",
        joinColumns = @JoinColumn(name="FLIGHT_ID"),
        inverseJoinColumns = @JoinColumn(name="COMP_ID")
    )
public X getX()...

So more lines of code for the ORM rather than properties or behavior!!! Sooner or later if an ORM needs to support client code it will end up like that. MapperDao embraces these needs instead of trying to hide them to "reduce" the number of lines. Also note that to read annotations you need reflection.
Activate doesn't need any annotation to do persistence. It uses convention over configuration in many points to avoid them. The 1.1 version will have an annotation @Alias(name:String) to create custom entity names and attributes. This is a commercial request that I will have to add to Activate.

    d.    MapperDao queries IMHO are more natural than Activate ones, probably due to mapperdao's mappings. I.e. copying from activate sample project:

    // Queries
    // The query operators available are :==, <, :>, <=, >=, isNone, isSome, :||, :&&, like and matches. 
    // Note that the queries can be made about abstract entities (abstract trait and class).
    // Perform queries within transactions
    transactional {
        val result = query {
            (person: Person) => where(person.name :== "John2") select (person)
        }
        for (person <- result)
            println(person.name)
    }

So why the ":>" operator instead of ">"? Why the ":||" or ":&&" ? MapperDao DSL had only to use "===" instead of "=="
Query operators are standardized using ":". It's my design choice.

The same query with mapperdao looks like a sql and hence a programmer doesn't have to learn anything new:

val pe=PersonEntity
(select from pe where pe.name === "John2").toList(queryDao)

the operators that you can use with mapperdao are === , > , < , <= , >= , and , or . Except the "===", the rest match a typical select SQL.

Also IMHO mapperdao DSL is more readable, i.e. compare:

activate:
query { (person: Person) => where(person.name :== "John2") select (person) }

mapperdao:
(select from pe where pe.name === "John2").toList(queryDao)
I don't like the SQL terms order:

select -> from -> where
(map -> source -> filter)

I implemented Activate to be more logical:

from -> where -> select
(source -> filter -> map)

For me, Activate queries are more readable. There are also other forms of query:

select[Person] where(_.name :== "John")
allWhere[Person](_.name :== "John")

Activate doesn't need this strange line of code:
val pe=PersonEntity
Mapperdao supports this scenarios that are supported by Activate?

Nested properties

query((p: Person) => where(p.mother.name :== "John") select(p))

Select entity values

query((p: Person) => where(p.name :== "John") select(p, p.mother))

Query based on a trait

trait User { body… } extends Entity
class Person { body… } extends User

query((u: User) => where(u.login = "abc") select(u))
4.    does activate support more than 1 database? It seems "transactional" and "query" are static and "magically" get the database connection. MapperDao supports multiple databases. What if the WebSite entity was stored across multiple databases? Which value from which database does the JVM instance reflect?
Yes, it supports multiple contexts with different databases. You are wrong, tansactional and query aren't static, they are from the persistence context instance import. 

5.    I still have to see how activate deals with auto-generated id's and also how many-to-many , one-to-many, many-to-one and one-to-one are mapped. I.e. when an entity contains a Set[X], is that a many to many or one to many?
Ok, just see it for yourself using Activate. If you have any trouble, I'm here. I answered the relation question in the original thread.

6.    And how does activate deal with inheritance?
Activate supports inheritance, including traits. It's possible even to do queries based on traits. Mapperdao also has this support?

There is more functionality that mapperdao's model allows. I.e. you can map entities that don't live in a database (i.e. entities retrieved via a web service call or maybe legacy Hibernate entities). Also it supports entities with composite primary keys and so on. MapperDao follows the principle "do one thing and do it well" allowing client code to have an STM layer on top if they wish.
You really don't understands what a STM is. Please, study it before saying that is possible to use a STM on top of Mapperdao. It's a hard problem.

Just to confirm, do you understand that Mapperdao has veiled mutability and inconsistent reads on the entity graph? There is any error or misuse of Mapperdao in my tests?

Finally, please before doing so many wrong statements, take a look and try to use Activate as a matter of respect. I did that with Mapperdao.

-- 
Flávio W. Brasil
{persistence as it should be}

Flávio W. Brasil

unread,
Nov 11, 2012, 8:14:50 PM11/11/12
to Kostas Kougios, Tim Pigden, scala-user
It's faster in any scenario.

-- 
Flávio W. Brasil
{persistence as it should be}

Flávio W. Brasil

unread,
Nov 11, 2012, 8:34:26 PM11/11/12
to Tim Pigden, Konstantinos Kougios, scala-user
Hello Tim,

Nice analysis about the situation.

I don't know how postgis works. Activate supports custom column types and database direct access. This features are sufficient?

About the ORM arena, you are right. Unfortunately the discussion is now beyond technical questions. I was thinking in not respond, but I couldn't avoid clarify so many wrong assumptions about Activate.

-- 
Flávio W. Brasil
{persistence as it should be}

Haoyi Li

unread,
Nov 11, 2012, 9:51:26 PM11/11/12
to Flávio W. Brasil, Tim Pigden, Konstantinos Kougios, scala-user
Flavio,

You said a while ago that you'd be writing up something about how Activate works inside. Have you had time to do that? I'm genuinely curious about how it works under the hood.

-Haoyi

Kostas kougios

unread,
Nov 12, 2012, 4:38:37 PM11/12/12
to scala...@googlegroups.com
Hi again Flavio, just to quickly clarify a few things,

"Carry it's weight" is suggested by Efficient Java book (I think) and means that an API shouldn't take shortcuts that might seem to simplify things because later on they actually make things harder. I.e. mapperdao weight is to O-R-M and there is mapping involved, hence no attempt to take shortcuts and avoid something that will be done anyway by someone that maps domain classes to databases.

Regarding the "veiled mutability" the way you present it, you are right, mapperdao has this, hibernate too, 100% of all jdbc code I've ever seen, and slick code has that as well, the thing is that I don't find it a problem at all and I've to say all of the projects I've worked on were like this. Values in the database are never in sync with those in memory and that's a fact of the way computers work. In reality things are just there and there is no need to "store" them or "persist" them but with computers entities exist in memory and they will be lost unless we store them in a database or somewhere else. In reality "everything changes" as Heraclitus said, where as in programming immutability is a best practise. For most projects it is not important if an entity is in absolute sync with the database. Entities are sort lived in memory most of the time anyway,i.e. in a web app they live for the duration of a request. Now if you make them immutable not only you can keep them in memory for much longer (as immutable objects can't be changed and you can reason about them in multiple threads and be sure that the 1 and only copy's state can't be corrupted) but also you avoid a lot of bugs and force your team to work with better coding practises.

By this I don't mean that a new idea like Activate is necessarily wrong. But I am still not clear on what kind of applications are you targeting.

Indeed I don't know much about STM, I don't have to. No project I've seen so far uses STM. STM been around since the 80ties with not much success means that I wouldn't bet my money on it.

Regarding activate been faster in all scenarios, do you have executable proof?

Flávio W. Brasil

unread,
Nov 14, 2012, 7:21:25 AM11/14/12
to Kostas kougios, scala...@googlegroups.com
Hello Kostas, 
 
Most ORMs, including Hibernate, has features to handle concurrency using explicit mutability and pessimistic/optimistic locking. So, they do not have a veiled mutability behind immutable classes. 
 
I am working in a project called databen.ch with Klaus (the creator of Prevayler). It will test persistence frameworks scalability and consistency. The project is in an initial state now.

-- 
Flávio W. Brasil
{persistence as it should be}

Flávio W. Brasil

unread,
Nov 14, 2012, 7:27:25 AM11/14/12
to Haoyi Li, scala-user
Haoyi,

The architecture documentation will be released with the 1.1 version, probably this month.

-- 
Flávio W. Brasil
{persistence as it should be}

Konstantinos Kougios

unread,
Nov 14, 2012, 8:32:20 AM11/14/12
to "Flávio W. Brasil", scala...@googlegroups.com
Can you point to a hibernate example that does this? As far as I know, hibernate doesn't manage instances of object in memory and you can have different in-memory modifications of the same row, each modification viewing it's own instance. It has support for version column but other than that the transaction model of hibernate is no different than mapperdao's.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages