Giter Site home page Giter Site logo

activate's Introduction

Activate Persistence Framework

Gitter

Activate splash

Documentation (index):

Introduction

Activate is a framework to persist objects in Scala. It is a STM (Software Transactional Memory) durable, with pluggable persistence. Its core is the RadonSTM, which provides a powerful mechanism for controlling transactions in memory, analogous to the transactions of databases, to do optimistic concurrency control. The durability of transactions (persistence) is pluggable and can use persistence in different paradigms such as relational (JDBC), prevalence (Prevayler) and non-relational (MongoDB).

Benefits

The main benefits of the framework are:

  • Atomic, consistent, isolated and durable transactions. You can use entities without worrying about concurrency issues.
  • Entities are always consistent in memory and in the persistence layer. For example, if rollback occurs, entities in memory stay consistent.
  • Transaction propagation control, including nested transactions.
  • Entities are lazy loaded and initialized automatically when needed.
  • Queries are type-safe and consistent, even with objects created in the current transaction. Therefore, an entity created in the same transaction may be returned in a query.
  • The available memory is used efficiently, minimizing the conversation with the storage and maximizing performance.

Build

Use sbt 0.11.2 to build Activate. Use the command "eclipse" to generate the eclipse project. To run tests, you have to provide the databases instances for the contexts defined on the net.fwbrasil.activate.ActivateTest.contexts method of the activate-tests project.

License

The code is licensed under LGPL.

activate's People

Contributors

akhodakivskiy avatar b0c1 avatar felipe-silva-mmar avatar felipeko avatar fwbrasil avatar gitter-badger avatar hmrm avatar justjoheinz avatar kangmo avatar kouphax avatar odwrotnie avatar scalalang2 avatar vchuravy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

activate's Issues

null transient vals

I noticed many or all of my transient vals were null, and was going to report this. Then I saw this:
https://github.com/fwbrasil/activate/blob/master/activate-tests/src/test/scala/net/fwbrasil/activate/entity/EntityTransientValueSpecs.scala

Are eager transient vals supposed to be initialized to null? If so, why would anyone use them?

This was fine with me though, as I wanted lazies anyway. I switched them over and things generally worked. However, I still got NPEs from time to time. I inserted a println into a single transaction (play controller) and ran it during a large (~120k line) loading of mock data into my app and got: event.projections: com.lti.RaceTracker.view.projection.EventProjections@ba63674 event.projections: null

Since entities are being updated rapidly its not surprising a transaction rollback would occur, but the result seems to be that the transient is null (and always null, even after I re-execute the transaction when the entities are no longer being updated). If I wait until after the data finishes loading the projections lazy val is always not null.

limit in queries

Hi,
I am wondering if it is possible to write a query in activate which is identical to the following sql:

SELECT * FROM users ORDER BY lastLogin DESC LIMIT 1

If it is possible please explain to me how.

Thanks

Exception thrown by LiveCache for trying to call None.get

I tried to integrate Activate into a simple play project but immediately got an error when trying to fetch something from the db.

I used this query:
def loadByEmail(email:String) = {
query {
(entity: User) =>
where(entity.email :== email) select (entity)
}
}

when passing an email that will surely return 0 users from the db everything is fine.
when passing an email that returns users I get this error stack:
! @6d3c2io1l - Internal server error, for request [GET /users?id=[email protected]] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1: Execution exception [[NoSuchElementException: None.get]]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:134) play_2.9.1.jar:2.0.4]
at play.core.ActionInvoker$$anonfun$receive$1.apply(Invoker.scala:115) [play_2.9.1.jar:2.0.4]
at akka.actor.Actor$class.apply(Actor.scala:318) [akka-actor.jar:2.0.2]
at play.core.ActionInvoker.apply(Invoker.scala:113) [play_2.9.1.jar:2.0.4]
at akka.actor.ActorCell.invoke(ActorCell.scala:626) [akka-actor.jar:2.0.2]
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) [akka-actor.jar:2.0.2]
Caused by: java.util.NoSuchElementException: None.get
at scala.None$.get(Option.scala:274) ~[scala-library.jar:0.11.3]
at scala.None$.get(Option.scala:272) ~[scala-library.jar:0.11.3]
at net.fwbrasil.activate.entity.EntityHelper$.getEntityClassFromId(EntityHelper.scala:52) ~[activate-core_2.9.1-
1.1.jar:1.1]
at net.fwbrasil.activate.cache.live.LiveCache.materializeEntity(LiveCache.scala:205) ~[activate-core_2.9.1-1.1.j
ar:1.1]
at net.fwbrasil.activate.cache.live.LiveCache.materializeEntityIfNotDeleted(LiveCache.scala:214) ~[activate-core
_2.9.1-1.1.jar:1.1]
at net.fwbrasil.activate.cache.live.LiveCache.materializeReference(LiveCache.scala:195) ~[activate-core_2.9.1-1.
1.jar:1.1]

following the trace leads me to these 2 methods in EntityHelper:

def getEntityClassFromIdOption(entityId: String) =
    if (entityId.length >= 35)
        entitiesMetadatas.get(normalizeHex(entityId.substring(37))).map(_.entityClass)
    else
        None

def getEntityClassFromId(entityId: String) =
    getEntityClassFromIdOption(entityId).get

Looks like the first one returns None and the second one tries to perform an ilegal get on it.

If you cant reproduce it and need more data just contact me.

Before/after signals.

As you said:

The cascade delete is a feature that I was thinking to add. Please, add a new issue with how you think that should be the support if you want it prioritized.

What about some kind of signals such as:

  • beforeSave,
  • afterSave,
  • beforeDelete,
  • afterDelete,
  • beforeUpdate,
  • afterUpdate?

Using Option[(Int,Int,Int)] fails to be enhanced when applying an Migration

Hi, im using an manual migration to create tables/columns, and i get the following exception:

play.api.UnexpectedException: Unexpected exception [ExceptionInInitializerError: null]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$3$$anonfun$1.apply(ApplicationProvider.scala:134) ~[play_2.9.1.jar:2.0.3]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$3$$anonfun$1.apply(ApplicationProvider.scala:112) ~[play_2.9.1.jar:2.0.3]
    at scala.Option.map(Option.scala:133) ~[scala-library.jar:0.11.3]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$3.apply(ApplicationProvider.scala:112) ~[play_2.9.1.jar:2.0.3]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$3.apply(ApplicationProvider.scala:110) ~[play_2.9.1.jar:2.0.3]
    at scala.Either$RightProjection.flatMap(Either.scala:277) ~[scala-library.jar:0.11.3]
Caused by: java.lang.ExceptionInInitializerError: null
    at Global$.onStart(Global.scala:13) ~[classes/:na]
    at play.api.GlobalPlugin.onStart(Global.scala:134) ~[play_2.9.1.jar:2.0.3]
    at play.api.Play$$anonfun$start$1.apply(Play.scala:60) ~[play_2.9.1.jar:2.0.3]
    at play.api.Play$$anonfun$start$1.apply(Play.scala:60) ~[play_2.9.1.jar:2.0.3]
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59) ~[scala-library.jar:0.11.3]
    at scala.collection.immutable.List.foreach(List.scala:45) ~[scala-library.jar:0.11.3]
Caused by: java.lang.IllegalStateException: Fail to enhance models.specification.Product
    at net.fwbrasil.activate.entity.EntityEnhancer$.enhance(EntityEnhancer.scala:95) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at net.fwbrasil.activate.entity.EntityEnhancer$.net$fwbrasil$activate$entity$EntityEnhancer$$enhance(EntityEnhancer.scala:115) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at net.fwbrasil.activate.entity.EntityEnhancer$$anonfun$4.apply(EntityEnhancer.scala:109) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at net.fwbrasil.activate.entity.EntityEnhancer$$anonfun$4.apply(EntityEnhancer.scala:109) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) ~[scala-library.jar:0.11.3]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) ~[scala-library.jar:0.11.3]
Caused by: javassist.NotFoundException: scala.Tuple3<Ljava.lang.Object;Ljava.lang.Object;Ljava.lang.Object;>
    at javassist.ClassPool.get(ClassPool.java:436) ~[javassist.jar:na]
    at javassist.ClassPool.getCtClass(ClassPool.java:501) ~[javassist.jar:na]
    at net.fwbrasil.activate.entity.EntityEnhancer$.net$fwbrasil$activate$entity$EntityEnhancer$$enhanceField(EntityEnhancer.scala:179) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at net.fwbrasil.activate.entity.EntityEnhancer$$anonfun$3.apply(EntityEnhancer.scala:88) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at net.fwbrasil.activate.entity.EntityEnhancer$$anonfun$3.apply(EntityEnhancer.scala:87) ~[activate-core_2.9.1-1.2-RC1.jar:1.2-RC1]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194) ~[scala-library.jar:0.11.3]

The migration is:

object DefaultMigration extends ManualMigration {
  def up = {
    createTableForAllEntities
      .ifNotExists
    createInexistentColumnsForAllEntities
  }
}

The model class is:

class Product(var code: String) extends Entity {
  var englishDescription: Option[String] = None
  var portugueseDescription: Option[String] = None
  var spanishDescription: Option[String] = None

  var deactivated: Option[Date] =  None

  var validityPeriod: Option[(Int,Int,Int)] = _
}

Without Option, (Int, Int, Int) does work as usual.

Using Activate 1.2-RC1 with Play 2.0.3 and Postgres 8.4

Is Scala 2.10-RC5 / 2.10.0 final supported?

Hi,

your framework seems great and I would like to use it in production within my company, but I don't see scala 2.10-RC5 compiled artifacts. It would be possible to generate one and put it in your maven repo?

In theory, since Scala 2.10.0 final is out, it would be great also to have an artifact for it, since probably we'll switch as soon as Spray and Akka will support it.

Cheers,
A.

Postgres connection failure with multiple play reloads

I'm using activate 1.2-RC6 with playframework and postgres as database.

Now and then when reloading the app I get this error

[error] c.j.b.BoneCP - Failed to acquire connection to jdbc:postgresql://127.0.0.1/dokee. Sleeping for 7000 ms. Attempts left: 1
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:291) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:108) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Connection.(AbstractJdbc2Connection.java:125) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3.AbstractJdbc3Connection.(AbstractJdbc3Connection.java:30) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.(AbstractJdbc3gConnection.java:22) ~[postgresql-9.1-901.jdbc4.jar:na]
[error] c.j.b.BoneCP - Failed to acquire connection to jdbc:postgresql://127.0.0.1/dokee. Sleeping for 7000 ms. Attempts left: 0
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:291) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:108) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Connection.(AbstractJdbc2Connection.java:125) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3.AbstractJdbc3Connection.(AbstractJdbc3Connection.java:30) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.(AbstractJdbc3gConnection.java:22) ~[postgresql-9.1-901.jdbc4.jar:na]
[error] c.j.b.PoolWatchThread - Error in trying to obtain a connection. Retrying in 7000ms
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:291) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:108) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc2.AbstractJdbc2Connection.(AbstractJdbc2Connection.java:125) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3.AbstractJdbc3Connection.(AbstractJdbc3Connection.java:30) ~[postgresql-9.1-901.jdbc4.jar:na]
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.(AbstractJdbc3gConnection.java:22) ~[postgresql-9.1-901.jdbc4.jar:na]
...(it keeps trying indefinitely till you close)

It looks like activate is not closing connections when playframework's hot reload is triggered. This error occur after a few reloads.

Please, lemme know if further info is needed in order to solve the issue.

Problem using EntityForm

Hi, i'm having a problem using EntityForm.

I'm trying to use it in a simple class:

class Product(var code: String) extends Entity {
  var englishDescription: Option[String] = None
  var portugueseDescription: Option[String] = None
  var spanishDescription: Option[String] = None
}

Using this way:

Logger.info(models.memoryContext.contextName)

  val productForm = EntityForm[Product](
    _.englishDescription -> optional(text),
    _.portugueseDescription -> optional(text),
    _.spanishDescription -> optional(text)
  )


    val product = Product("produto qualquer")
    transactional {
      productForm.fillWith(product)
    }

And i get the following exception:

java.lang.ExceptionInInitializerError: null
    at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:32) ~[classes/:na]
    at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:32) ~[classes/:na]
    at play.core.Router$HandlerInvoker$$anon$3.call(Router.scala:1080) ~[play_2.9.1.jar:2.0.3]
    at play.core.Router$Routes$class.invokeHandler(Router.scala:1255) ~[play_2.9.1.jar:2.0.3]
    at Routes$.invokeHandler(routes_routing.scala:14) ~[classes/:na]
    at Routes$$anonfun$routes$1$$anonfun$apply$1.apply(routes_routing.scala:32) ~[classes/:na]
Caused by: java.lang.IllegalArgumentException: requirement failed
    at scala.Predef$.require(Predef.scala:145) ~[scala-library.jar:0.11.3]
    at net.fwbrasil.activate.play.EntityForm$.build(EntityForm.scala:59) ~[activate-play_2.9.1-1.2-RC1.jar:1.2-RC1]
    at net.fwbrasil.activate.play.EntityForm$.apply(EntityForm.scala:53) ~[activate-play_2.9.1-1.2-RC1.jar:1.2-RC1]
    at controllers.Application$.<init>(Application.scala:14) ~[classes/:na]
    at controllers.Application$.<clinit>(Application.scala) ~[classes/:na]
    at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:32) ~[classes/:na]

I am not sure if it's a problem with my code or a bug.

Unwanted autosave in request transaction

I have bound the transaction to request and it autosaves all entities in it.

What should I do when the entity is used by a form and user clicks cancel button?

Cannot change column database type

Hi, i'm trying to change the column type on the database.
The docs says to use a customColumn, like this:
_.customColumn[String]("attribute1", "CLOB")

But i cannot do it directly, so i tried using rename column (and then i would rename it back):
table[Person].renameColumn("name", _.customColumn[String]("_name","text") )
But although the column name is altered the type is not.

Query normalization fails for nested properties

case class Book(title: String, authorId: String) extends Entity {
def categories = select[BookCategory].where(.book :== this).map(.category)
}
case class BookCategory(book: Book, category: Category) extends Entity
case class Category(name: String) extends Entity

val horrorBooks = transactional {
query { (book: Book, relation: BookCategory) =>
where((relation.book :== book) :&& (relation.category.name :== "Horror")) select (book)
}
}

ERROR

org.h2.jdbc.JdbcSQLException: Column "S1.ID" not found; SQL statement:
SELECT s1.id FROM "BOOKCATEGORY" s2, "CATEGORY" t1 WHERE (s2."BOOK" = s1.id and t1."NAME" = ? and s2."CATEGORY" = t1.id)

Use the data mapper pattern

http://en.wikipedia.org/wiki/Data_mapper_pattern

Long story short, the data mapper pattern means you completely separate the object implementation from the underlying persistance in your actual scala code

An example of how slick does this is shown here

case class Device(id: Long, 
 price: Double, 
 acquisition: Date) 

As you can see from the above, there is no extending any Table (or activates Entity)

This is done later on (in Slick) with

class Devices extends Table[Device]("DEVICE") { 
def id = column[Long]("ID", O.PrimaryKey) 
def price = column[String]("PRICE") 
def acquisition = column[Date]("ACQUISITION") 
 def * = id ~ price ~ acquisition <> 
 (Device.apply _, Device.unapply _) 
}

The advantages of data mapper pattern are quite obvious. It enables better sharing of code (your models aren't tied to the database, so you can place common code in models and use them differently), faster/easier testing (since your models aren't linked to any database library, its very easy to create mocks and for the same reason, testing is very fast since you are just creating in memory scala models)

The equivalent in activate (as an example) would be to just create a Device class

class Device(price: Double, 
 acquisition: Date) 

And then there would be some factory which would extend the Device class (which provides a way to create a new Device inside the transactional blocks)

String index out of range while orderBy(user.creationTimestamp)

While ordering by creationTimestamp you get an error:

Exception occured while processing /accounts/create
Message: java.lang.StringIndexOutOfBoundsException: String index out of range: 35
    java.lang.String.substring(String.java:1934)
    net.fwbrasil.activate.entity.Entity$class.creationTimestamp(Entity.scala:80)
    model.accounts.User.creationTimestamp(User.scala:11)

Invalid [@transient] entity property type. Event.enum: interface play.api.libs.iteratee.Enumerator

I am trying to associate a play enumerator with each of my entities. I get the above error when adding something as simple as the following to any of my entities:
@transient val enum = play.api.libs.iteratee.Enumerator(1,2,3)

I can add other sorts of transient values to the same entity (I have an actor associated with it currently) without issue. I made the following test to try and reproduce the problem: https://gist.github.com/gbeaty/d783bfa9a1e58ac86dee

However, the test passes successfully. Unfortunately I can't seem to reproduce the issue.

This is with Scala 2.10 and Activate 1.2-RC4. Full stack trace:

[error] ThrowableException: null (TraversableLike.scala:244) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] net.fwbrasil.activate.entity.EntityPropertyMetadata$$anonfun$14.apply(EntityMetadata.scala:67) [error] net.fwbrasil.activate.entity.EntityPropertyMetadata$$anonfun$14.apply(EntityMetadata.scala:67) [error] net.fwbrasil.activate.entity.EntityPropertyMetadata.<init>(EntityMetadata.scala:67) [error] net.fwbrasil.activate.entity.EntityMetadata$$anonfun$19.apply(EntityMetadata.scala:100) [error] net.fwbrasil.activate.entity.EntityMetadata$$anonfun$19.apply(EntityMetadata.scala:99) [error] net.fwbrasil.activate.entity.EntityMetadata.<init>(EntityMetadata.scala:99) [error] net.fwbrasil.activate.entity.EntityHelper$$anonfun$initialize$1.apply(EntityHelper.scala:43) [error] net.fwbrasil.activate.entity.EntityHelper$$anonfun$initialize$1.apply(EntityHelper.scala:39) [error] net.fwbrasil.activate.entity.EntityHelper$.initialize(EntityHelper.scala:39) [error] net.fwbrasil.activate.ActivateContext$class.$init$(ActivateContext.scala:43) [error] com.lti.RaceTracker.model.PersistenceContext$.<init>(Persistence.scala:23) [error] com.lti.RaceTracker.model.PersistenceContext$.<clinit>(Persistence.scala) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] null [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] Invalid entity property type. Event.enum: interface play.api.libs.iteratee.Enumerator [error] net.fwbrasil.activate.entity.EntityPropertyMetadata$$anonfun$14.apply(EntityMetadata.scala:67) [error] net.fwbrasil.activate.entity.EntityPropertyMetadata$$anonfun$14.apply(EntityMetadata.scala:67) [error] net.fwbrasil.activate.entity.EntityPropertyMetadata.<init>(EntityMetadata.scala:67) [error] net.fwbrasil.activate.entity.EntityMetadata$$anonfun$19.apply(EntityMetadata.scala:100) [error] net.fwbrasil.activate.entity.EntityMetadata$$anonfun$19.apply(EntityMetadata.scala:99) [error] net.fwbrasil.activate.entity.EntityMetadata.<init>(EntityMetadata.scala:99) [error] net.fwbrasil.activate.entity.EntityHelper$$anonfun$initialize$1.apply(EntityHelper.scala:43) [error] net.fwbrasil.activate.entity.EntityHelper$$anonfun$initialize$1.apply(EntityHelper.scala:39) [error] net.fwbrasil.activate.entity.EntityHelper$.initialize(EntityHelper.scala:39) [error] net.fwbrasil.activate.ActivateContext$class.$init$(ActivateContext.scala:43) [error] com.lti.RaceTracker.model.PersistenceContext$.<init>(Persistence.scala:23) [error] com.lti.RaceTracker.model.PersistenceContext$.<clinit>(Persistence.scala) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25) [error] com.lti.RaceTracker.model.ModelTests$$anonfun$2$$anonfun$apply$13.apply(ModelTests.scala:25)

java.lang.IllegalStateException: Triyng to access a destroyed ref.

I'm seeing this error after running a process with about 25-100 reads/writes a minute for around 15-30 minutes. The line that seems to be blowing up is this:

transactional { val result = select[SocialMediaStatus] where(_.socialMediaId :== status.getId, _.socialNetwork :== SocialNetwork.Twitter)
......

Without getting too detailed, status is a Twitter4j.Status object, so this query is basically checking whether or not we've already stored the status. Here's the error I'm getting from that query, which only happens intermittently

java.lang.IllegalStateException: Triyng to access a destroyed ref. at net.fwbrasil.radon.transaction.RefSnapshooter.validateIfDestroyed(RefSnapshooter.scala:60) at net.fwbrasil.radon.transaction.RefSnapshooter.getSnapshot(RefSnapshooter.scala:36) at net.fwbrasil.radon.transaction.RefSnapshooter.getSnapshot(RefSnapshooter.scala:22) at net.fwbrasil.radon.transaction.RefSnapshooter.snapshotRead(RefSnapshooter.scala:41) at net.fwbrasil.radon.transaction.Transaction.get(Transaction.scala:53) at net.fwbrasil.radon.ref.Ref.get(Ref.scala:109) at net.fwbrasil.activate.entity.Var.net$fwbrasil$activate$entity$Var$$super$get(Var.scala:63) at net.fwbrasil.activate.entity.Var$$anonfun$get$1.apply(Var.scala:63) at net.fwbrasil.activate.entity.Var$$anonfun$get$1.apply(Var.scala:60) at net.fwbrasil.activate.entity.Var.doInitialized(Var.scala:102) at net.fwbrasil.activate.entity.Var.get(Var.scala:60) at net.fwbrasil.activate.entity.Var.getValue(Var.scala:68) at net.fwbrasil.activate.cache.live.LiveCache.entityProperty(LiveCache.scala:494) at net.fwbrasil.activate.cache.live.LiveCache.entityPropertyPathRef(LiveCache.scala:477) at net.fwbrasil.activate.cache.live.LiveCache.executeStatementEntitySourceValue(LiveCache.scala:466) at net.fwbrasil.activate.cache.live.LiveCache.executeStatementEntityValue(LiveCache.scala:459) at net.fwbrasil.activate.cache.live.LiveCache.executeStatementSelectValue(LiveCache.scala:449) at net.fwbrasil.activate.cache.live.LiveCache.executeStatementValue(LiveCache.scala:431) at net.fwbrasil.activate.cache.live.LiveCache.executeCompositeOperatorCriteria(LiveCache.scala:348) at net.fwbrasil.activate.cache.live.LiveCache.executeCriteria(LiveCache.scala:344) at net.fwbrasil.activate.cache.live.LiveCache.executeStatementBooleanValue(LiveCache.scala:421) at net.fwbrasil.activate.cache.live.LiveCache.executeBooleanOperatorCriteria(LiveCache.scala:411) at net.fwbrasil.activate.cache.live.LiveCache.executeCriteria(LiveCache.scala:340) at net.fwbrasil.activate.cache.live.LiveCache.executeQueryWithEntitySourcesMap(LiveCache.scala:297) at net.fwbrasil.activate.cache.live.LiveCache$$anonfun$executeQueryWithEntitySources$1.apply(LiveCache.scala:278) at net.fwbrasil.activate.cache.live.LiveCache$$anonfun$executeQueryWithEntitySources$1.apply(LiveCache.scala:277) at scala.collection.immutable.List.foreach(List.scala:318) at net.fwbrasil.activate.cache.live.LiveCache.executeQueryWithEntitySources(LiveCache.scala:277) at net.fwbrasil.activate.cache.live.LiveCache.entitiesFromCache(LiveCache.scala:159) at net.fwbrasil.activate.cache.live.LiveCache.executeQuery(LiveCache.scala:184) at net.fwbrasil.activate.statement.query.QueryContext$$anonfun$1.apply(QueryContext.scala:29) at net.fwbrasil.activate.statement.query.QueryContext$$anonfun$1.apply(QueryContext.scala:28) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) at scala.collection.immutable.List.foreach(List.scala:318) at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) at scala.collection.AbstractTraversable.map(Traversable.scala:105) at net.fwbrasil.activate.statement.query.QueryContext$class.executeQuery(QueryContext.scala:28)
...

I can try and setup an example project that replicates the issue, but wanted to get this in front of you and see if there was a quick explanation or fix first.

Generic trait query

This snippet:

trait TreeNode[N <: TreeNode[N]] {

  self: Entity =>

  var parent: Option[N] = None

  def children: List[N] = transactional {
    query {
      (node: N) => where(node.parent :== this) select (node)
    }
  }

  def toPath: String =
    List(Some(toString), parent.map(_.toPath)).flatten.mkString(" / ")
}

produces error:

[error] /Volumes/Home/activate-persistence/src/main/scala/models/Model.scala:18: value : is not a member of Option[N]
[error]       (node: N) => where(node.parent :== this) select (node)
[error]                                      ^

null entity vars after initialization

I've been trying to reproduce this issue outside of my app, without success.

Essentially I'm creating an entity and an actor. The actor takes the entity as a constructor parameter and handles some sequential message receiving for that entity. Everything is fine until the actor runs, when the entity's vars seem to be null.

For example, if I println the entity after its created:

Event(demo -> false, liveSession -> , sessions -> List(), timingSystemId -> 1, track -> Daytona International Speedway, _videos -> List(), actualEndDate -> , id -> 1b00db7c-c99f-11e2-a0a0-cbd5058d54bc-403827a0, lid -> 4, scheduledStartDate -> 2013-05-30T23:06:35.379-04:00, _timeZoneOffset -> , description -> , stateId -> 1, name -> 2013-05-26_ChumpCar_Daytona, scheduledEndDate -> , announcements -> List(), actualStartDate -> , raceTypeId -> 1, man -> racewatcher.model.Event)

As it should be. Then if I println the same entity inside the actor:

Event(demo -> , liveSession -> , sessions -> , timingSystemId -> ,track -> , _videos -> , actualEndDate -> , id -> 1b00db7c-c99f-11e2-a0a0-cbd5058d54bc-403827a0, lid -> , scheduledStartDate -> , _timeZoneOffset -> , description -> , stateId -> , name -> , scheduledEndDate -> , announcements -> , actualStartDate -> , raceTypeId -> , man -> )

All nulls. Note the initial println comes before the actor's, so the entity is obviously initialized correctly. However in the actor's transaction all its vars appear to be null.

I tried to reproduce it here, but failed:
https://gist.github.com/gbeaty/8194a40706355e7013ef

Referential integrity constraint violation

What is wrong with the following approach?

Model:

class Geoloc(val name: String, val parent: Option[Geoloc]) extends Entity
class Country(n: String) extends Geoloc(n, None)
class City(n: String, country: Country) extends Geoloc(n, Some(country))

Code:

val poland = new Country("Poland")
val bydgoszcz = new City("Bydgoszcz", poland)

Exception:

net.fwbrasil.activate.storage.relational.JdbcStatementException: Statement exception: INSERT INTO "CITY" ("CREATED", "ID", "NAME", "PARENT")  VALUES (:created, :id, :name, :parent). Next exception: Some(Referential integrity constraint violation: "CITY_PARENT: PUBLIC.CITY FOREIGN KEY(PARENT) REFERENCES PUBLIC.GEOLOC(ID) ('8ecb706f-1ec3-11e3-9445-e557c4cf9b0a-9c4fef76')"; SQL statement:
INSERT INTO "CITY" ("CREATED", "ID", "NAME", "PARENT")  VALUES (?, ?, ?, ?) [23506-173])

Possibility to use different serializers

When trying to use an serializable and unsupported property like var phones: mutable.ArraySeq[String] = _, Activate creates an bytea column (on Postgresql, possibly the same thing occurs on others databases). Activate then uses java's serialization to write and read this column.

While It works nicely (you can read and write the attribute just fine), on the database it stay in a non-human readable format, like this:
'\254\355\000\005sr\000;net.fwbrasil.activate.serialization.JavaSerializatorEvelope9f\004\246\265I\232\313\002\000\001L\000\005valuet\000\022Ljava/lang/Object;xpsr\000!scala.collection.mutable.ArraySeq\025<=\322(I\016s\002\000\002I\000\006length[\000\005arrayt\000\023[Ljava/lang/Object;xp\000\000\000\002ur\000\023[Ljava.lang.Object;\220\316X\237\020s)l\002\000\000xp\000\000\000\002t\000\013424-4412213t\000\011555-55555'

It would be nice to have a way to change this serialization method, so one could use json or any other serialization format.

One simple way to achieve this feature, could look like this, using annotations:

@Serializable(PhoneEncoder) var phones: mutable.ArraySeq[String] = _

Then PhoneEncoder would have to extend an Serialization trait from Activate Framework:

trait Serialization {
   type T
   def encode(value: T):  Array[Byte]
   def decode(value: Array[Byte]) : T
}

The use of Array[Byte] is because this feature not need to take in account a different type of column (bytea is fine for most cases). An future feature could enable the change of column type, so the user can take advantage optimizing the database native data types, like Postgre's json and array type.

@Alias

it is not working in 1.3 version.

Example:

@Alias("foo")
case class Foo(@Alias("foo_name") name: String) extends Entity

Migration

table[Foo]
      .createTable(
      _.column[String]("foo_name")
    )

A destroyed ref was used

While deleting some objects I have got an error:

Exception occured while processing /accounts/list
Message: java.lang.IllegalStateException: A destroyed ref was used.
    net.fwbrasil.radon.transaction.TransactionValidator.validateDestroyed(TransactionValidator.scala:29)
    net.fwbrasil.radon.transaction.Transaction$$anonfun$net$fwbrasil$radon$transaction$Transaction$$validateTransaction$2.apply(Transaction.scala:176)
    net.fwbrasil.radon.transaction.Transaction$$anonfun$net$fwbrasil$radon$transaction$Transaction$$validateTransaction$2.apply(Transaction.scala:174)
    scala.collection.immutable.List.foreach(List.scala:318)
    scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:32)
    scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
    net.fwbrasil.radon.transaction.Transaction.net$fwbrasil$radon$transaction$Transaction$$validateTransaction(Transaction.scala:174)
    net.fwbrasil.radon.transaction.Transaction.commit(Transaction.scala:121)
    net.fwbrasil.radon.transaction.Transaction.commit(Transaction.scala:71)
    net.fwbrasil.radon.transaction.TransactionManager.runInTransactionWithRetry(TransactionManager.scala:77)
    net.fwbrasil.radon.transaction.TransactionManager.runInNewTransactionWithRetry(TransactionManager.scala:69)
    net.fwbrasil.radon.transaction.Required.execute(Propagation.scala:26)
    net.fwbrasil.radon.transaction.TransactionContext$class.transactional(TransactionContext.scala:47)
    model.Context$.transactional(Context.scala:9)
    net.fwbrasil.radon.transaction.TransactionContext$class.transactional(TransactionContext.scala:26)
    model.Context$.transactional(Context.scala:9)
    transaction.Transaction$.apply(Transaction.scala:8)
    bootstrap.liftweb.Boot$$anon$1.apply(Boot.scala:36)
    net.liftweb.http.S$class.net$liftweb$http$S$$doAround(S.scala:1390)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_nest2InnerInit$1.apply(S.scala:1623)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$class.net$liftweb$http$S$$_nest2InnerInit(S.scala:1622)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_innerInit$1$$anonfun$apply$41$$anonfun$apply$42$$anonfun$apply$43$$anonfun$apply$44.apply(S.scala:1666)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$withReq$1.apply(S.scala:1676)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$class.withReq(S.scala:1675)
    net.liftweb.http.S$.withReq(S.scala:47)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_innerInit$1$$anonfun$apply$41$$anonfun$apply$42$$anonfun$apply$43.apply(S.scala:1662)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_innerInit$1$$anonfun$apply$41$$anonfun$apply$42.apply(S.scala:1660)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_innerInit$1$$anonfun$apply$41.apply(S.scala:1659)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_innerInit$1.apply(S.scala:1658)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$class.net$liftweb$http$S$$_innerInit(S.scala:1657)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_init$1$$anonfun$apply$47$$anonfun$apply$48$$anonfun$apply$49$$anonfun$apply$50$$anonfun$apply$51.apply(S.scala:1699)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_init$1$$anonfun$apply$47$$anonfun$apply$48$$anonfun$apply$49$$anonfun$apply$50.apply(S.scala:1697)
    net.liftweb.http.CoreRequestVarHandler$class.apply(Vars.scala:613)
    net.liftweb.http.RequestVarHandler$.apply(Vars.scala:515)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_init$1$$anonfun$apply$47$$anonfun$apply$48$$anonfun$apply$49.apply(S.scala:1696)
    net.liftweb.http.CoreRequestVarHandler$class.apply(Vars.scala:613)
    net.liftweb.http.TransientRequestVarHandler$.apply(Vars.scala:528)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_init$1$$anonfun$apply$47$$anonfun$apply$48.apply(S.scala:1695)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_init$1$$anonfun$apply$47.apply(S.scala:1694)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$$anonfun$net$liftweb$http$S$$_init$1.apply(S.scala:1693)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.S$class.net$liftweb$http$S$$_init(S.scala:1692)
    net.liftweb.http.S$class.init(S.scala:1274)
    net.liftweb.http.S$.init(S.scala:47)
    net.liftweb.http.LiftServlet.doSession$1(LiftServlet.scala:300)
    net.liftweb.http.LiftServlet.doService(LiftServlet.scala:310)
    net.liftweb.http.LiftServlet$$anonfun$doIt$1$1.apply(LiftServlet.scala:148)
    net.liftweb.http.LiftServlet$$anonfun$doIt$1$1.apply(LiftServlet.scala:147)
    net.liftweb.util.TimeHelpers$class.calcTime(TimeHelpers.scala:345)
    net.liftweb.util.Helpers$.calcTime(Helpers.scala:34)
    net.liftweb.util.TimeHelpers$class.logTime(TimeHelpers.scala:364)
    net.liftweb.util.Helpers$.logTime(Helpers.scala:34)
    net.liftweb.http.LiftServlet.doIt$1(LiftServlet.scala:147)
    net.liftweb.http.LiftServlet.service(LiftServlet.scala:158)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply$mcV$sp(HTTPProvider.scala:72)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(HTTPProvider.scala:71)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(HTTPProvider.scala:71)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.URLRewriter$.doWith(Req.scala:1278)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2$$anonfun$apply$mcV$sp$1.apply$mcV$sp(HTTPProvider.scala:70)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2$$anonfun$apply$mcV$sp$1.apply(HTTPProvider.scala:70)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2$$anonfun$apply$mcV$sp$1.apply(HTTPProvider.scala:70)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2.apply$mcV$sp(HTTPProvider.scala:66)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2.apply(HTTPProvider.scala:60)
    net.liftweb.http.provider.HTTPProvider$$anonfun$service$2.apply(HTTPProvider.scala:60)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.provider.HTTPProvider$class.service(HTTPProvider.scala:60)
    net.liftweb.http.LiftFilter.service(LiftServlet.scala:928)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply$mcV$sp(ServletFilterProvider.scala:82)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(ServletFilterProvider.scala:82)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1$$anonfun$apply$mcV$sp$1$$anonfun$apply$mcV$sp$2.apply(ServletFilterProvider.scala:82)
    net.liftweb.http.provider.servlet.ServletFilterProvider$class.handleLoan$1(ServletFilterProvider.scala:59)
    net.liftweb.http.provider.servlet.ServletFilterProvider$class.net$liftweb$http$provider$servlet$ServletFilterProvider$$handleLoanWrappers(ServletFilterProvider.scala:63)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(ServletFilterProvider.scala:82)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1$$anonfun$apply$mcV$sp$1.apply(ServletFilterProvider.scala:77)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1$$anonfun$apply$mcV$sp$1.apply(ServletFilterProvider.scala:77)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16$$anonfun$apply$17.apply(Vars.scala:619)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16.apply(Vars.scala:618)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14$$anonfun$apply$15.apply(Vars.scala:617)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14.apply(Vars.scala:616)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$class.apply(Vars.scala:615)
    net.liftweb.http.RequestVarHandler$.apply(Vars.scala:515)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1.apply$mcV$sp(ServletFilterProvider.scala:75)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1.apply(ServletFilterProvider.scala:75)
    net.liftweb.http.provider.servlet.ServletFilterProvider$$anonfun$doFilter$1.apply(ServletFilterProvider.scala:75)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16$$anonfun$apply$17.apply(Vars.scala:619)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14$$anonfun$apply$15$$anonfun$apply$16.apply(Vars.scala:618)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14$$anonfun$apply$15.apply(Vars.scala:617)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$$anonfun$apply$14.apply(Vars.scala:616)
    net.liftweb.util.ThreadGlobal.doWith(ThreadGlobal.scala:71)
    net.liftweb.http.CoreRequestVarHandler$class.apply(Vars.scala:615)
    net.liftweb.http.TransientRequestVarHandler$.apply(Vars.scala:528)
    net.liftweb.http.provider.servlet.ServletFilterProvider$class.doFilter(ServletFilterProvider.scala:74)
    net.liftweb.http.LiftFilter.doFilter(LiftServlet.scala:928)
    org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1307)
    org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:453)
    org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:559)
    org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1072)
    org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:382)
    org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1006)
    org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    org.eclipse.jetty.server.Server.handle(Server.java:361)
    org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:485)
    org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:926)
    org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:988)
    org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:635)
    org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
    org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:627)
    org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:51)
    org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    java.lang.Thread.run(Thread.java:680)

foreign keys are not created

Hi,

I have the following entities:

case class Post(title:String, postedAt:Date, content:String, author:User) extends Entity
case class User(email:String, password:String, fullName:String, isAdmin:Boolean ) extends Entity

I am using PostgreSQL and the author field in post table is not a foreign key, just a simple varchar.
Is it a bug or a feature? If it is a feature how can I create foreign keys?

remove inexistent column

I was trying to remove a column from a table with the following code:

table[ToolRevision]
  .removeColumn("videoSource")
  .ifExists

table[ToolRevision]
  .removeColumn("videoFormat")
  .ifExists

Well I think that there is something wrong woth the "ifExists" part. I got the exception shown below:

! Internal server error, for request [GET /] ->

java.lang.ExceptionInInitializerError: null
at controllers.ToolController$.(ToolController.scala:67) ~[classes/:na]
at controllers.ToolController$.(ToolController.scala) ~[classes/:na]
at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:284) ~[classes/:na]
at Routes$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(routes_routing.scala:284) ~[classes/:na]
at play.core.Router$HandlerInvoker$$anon$4.call(Router.scala:1084) ~[play_2.9.1.jar:2.0.4]
at play.core.Router$Routes$class.invokeHandler(Router.scala:1259) ~[play_2.9.1.jar:2.0.4]
Caused by: net.fwbrasil.activate.storage.relational.JdbcStatementException: Statement exception: ALTER TABLE ToolRevision DROP COLUMN videoSource restriction (SELECT COUNT(1) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = (SELECT DATABASE()) AND TABLE_NAME = 'ToolRevision' AND COLUMN_NAME = 'videoSource',1)
at net.fwbrasil.activate.storage.relational.JdbcRelationalStorage$class.execute(JdbcRelationalStorage.scala:94) ~[activate-jdbc_2.9.1-1.2-RC2.jar:1.2-RC2]
at models.computerPersistenceContext$$anon$1.execute(computerPersistenceContext.scala:11) ~[classes/:na]
at net.fwbrasil.activate.storage.relational.JdbcRelationalStorage$$anonfun$executeStatements$1$$anonfun$apply$1.apply(JdbcRelationalStorage.scala:61) ~[activate-jdbc_2.9.1-1.2-RC2.jar:1.2-RC2]
at net.fwbrasil.activate.storage.relational.JdbcRelationalStorage$$anonfun$executeStatements$1$$anonfun$apply$1.apply(JdbcRelationalStorage.scala:60) ~[activate-jdbc_2.9.1-1.2-RC2.jar:1.2-RC2]
at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59) ~[scala-library.jar:0.11.3]
at scala.collection.immutable.List.foreach(List.scala:45) ~[scala-library.jar:0.11.3]
Caused by: java.sql.BatchUpdateException: Can't DROP 'videoSource'; check that column/key exists
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1666) ~[mysql-connector-java-5.1.6.jar:na]
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1082) ~[mysql-connector-java-5.1.6.jar:na]
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeBatch(NewProxyPreparedStatement.java:1353) ~[c3p0-0.9.2-pre4.jar:0.9.2-pre4]
at net.fwbrasil.activate.storage.relational.JdbcRelationalStorage$class.execute(JdbcRelationalStorage.scala:89) ~[activate-jdbc_2.9.1-1.2-RC2.jar:1.2-RC2]
at models.computerPersistenceContext$$anon$1.execute(computerPersistenceContext.scala:11) ~[classes/:na]
at net.fwbrasil.activate.storage.relational.JdbcRelationalStorage$$anonfun$executeStatements$1$$anonfun$apply$1.apply(JdbcRelationalStorage.scala:61) ~[activate-jdbc_2.9.1-1.2-RC2.jar:1.2-RC2]

My config is:
activate version: 1.2-RC2
play version: 2.04

Test data is not cleanup after running

Working a sample project that is described in issue #23 (with the changes to fix #23).

I found out the test case "create new computer" didn't clean up test data after running. I supposed it should do so. Moreover, the test populated testing data to developing database (in this case, I use postgresql) but not memory like what I expected when using additionalConfiguration = inMemoryDatabase() {...}.

Here is the code
https://gist.github.com/doanphihai/eec40115ead6d035bf4d

transient values in entities?

Hi,

I have the following models:

case class Post(title:String, postedAt:Date, content:String, author:User) extends Entity {
lazy val comments = transactional{
select[Comment] where(_.post :== this)
}
}
case class Comment(author:String, postedAt:Date, content:String, post:Post) extends Entity

And i got the following exception: Execution exception[[PSQLException: ERROR: column s1.comments does not exist Position: 63]]

Can I create transient fields in entities like I could in hibernate with the @transient annotation?
Can I use bi-directional relations in activate? Is there an equivalent to @OneToMany(mappedBy="post") public List comments; ?

Thanks

Support Cassandra

Is it possible to provide support for Cassandra? With CQL3, I believe it would be fairly straight forward now. I would be glad to contribute in some fashion to enable this support.

Regards,
Todd

Use of Lists on entities fails to create correct tables using migrations

Using Activate 1.1-RC1 and Postgresql 8.4
Trying to create entities with List properties gives exception when inserting new rows.

Usecase:

class User {
    var emails: List[String] = _
}

class CreateSchema extends Migration {
    def timestamp = 201211052223l
    def up = {
        createTableForAllEntities.ifNotExists
        createInexistentColumnsForAllEntities
    }
}

Executing:

new User()
user.emails = List("[email protected]")

Gives the exception:
BatchUpdateException: Batch entry 0 INSERT INTO "useremails" ("owner", "value") VALUES ('76f18f57-27a7-11e2-942e-ad37dc983e1c-d31fc7ff', '76f279b8-27a7-11e2-942e-ad37dc983e1c-5b4d8b0e') was aborted. Call getNextException to see the cause.

The problem happens because the value column in usermails has length 1.

Statement cache ignoring changes to limit() clause

When running a query, it caches the first value passed to limit, and then never updates it even if changed. It looks like the statement gets loaded from cache here in Statement:

protected def executeStatementWithCache[S <: Statement, R](f: Function, produce: () => S, execute: (S) => R, manifests: Manifest[_]*): R = {
        val (fields, stack) =
            cache.synchronized {
                cache.getOrElseUpdate((f.getClass.asInstanceOf[Class[_]], manifests), {
                    val fields = f.getClass.getDeclaredFields.toList.filter(field => !Modifier.isStatic(field.getModifiers))
                    fields.foreach(_.setAccessible(true))
                    (fields, new Stack[(Function, Statement)]())
                })
            }

I'm running on Activate 1.3.2

Enumerator is not being read from database

Hi, i'm trying to persist an Enumerator, and everything works fine (it persists the value in the database, and the value in the memory is ok). But after restarting the server, Activate does not read the value from the database.

Using Play 2.0.3, Activate 1.2-RC2 and Postgres 8.4.

My classes are:
Model

package models

import java.util.Date
import models.postgresContext._

class Product(var code: String,var productType: ProductType.ProductType) extends Entity 

object Product {
  def apply(code: String, productType: ProductType.ProductType) = {
    new Product(code,productType)
  }
  def find(id: String) = {
    byId[Product](id).get
  }

}

object ProductType extends Enumeration {
    case class ProductType(name:String) extends Val(name) 

    val KIT = ProductType("KIT")
    val ITEM = ProductType("ITEM")
}

Controller

package controllers

import models._
import play.api.data.Forms._
import play.api.mvc._
import play.api.Logger
import net.fwbrasil.activate.play.EntityForm
import models.postgresContext._

object Application extends Controller {

  def index = Action {
    transactional {
      val product = Product("code",ProductType.ITEM)
      Redirect(routes.Application.show(product.id))
    }
  }

  def show(id: String) = Action {
    transactional {
      Ok("Type: "+Product.find(id).productType)
    }
  }
}

When i open index, it works well, storing the product with the corret productType on the database and redirecting to show action, and rendering the correct productType. But if i restart the server and refresh de show page, it will show null, even thought the database record looks correct.

IllegalStateException: Can't find a concrete class for class models

Hi I've got following exception when run "play test". I modified the sample computer-databases from Play example based on activate's document. The thing is the project run OK. So I don't know what wrong with the tests.
I run with play 2.1.0, Activate 1.2-RC4 + postgresql 9.1 and scala 2.10

Here is the exception
[info] Application should
[info] + redirect to the computer list on /
[error] ! list computers on the the first page
[error] IllegalStateException: Can't find a concrete class for class models.Computer.
[error] Maybe the context isn't initialized or you must override acceptEntity on your context.
[error] Important: The context definition must be declared in a base package of the entities packages.
[error] Example: com.app.myContext for com.app.model.MyEntity (StatementMocks.scala:95)
[error] net.fwbrasil.activate.statement.StatementMocks$$anonfun$1.apply(StatementMocks.scala:95)
[error] net.fwbrasil.activate.statement.StatementMocks$$anonfun$1.apply(StatementMocks.scala:95)
[error] net.fwbrasil.activate.statement.StatementMocks$.mockEntity(StatementMocks.scala:94)
[error] net.fwbrasil.activate.statement.StatementMocks$.mockEntityWithoutCache(StatementMocks.scala:91)
[error] net.fwbrasil.activate.statement.StatementMocks$$anonfun$mockEntity$1.apply(StatementMocks.scala:88)
[error] net.fwbrasil.activate.statement.StatementMocks$$anonfun$mockEntity$1.apply(StatementMocks.scala:88)
[error] net.fwbrasil.activate.statement.StatementMocks$.mockEntity(StatementMocks.scala:88)
[error] net.fwbrasil.activate.statement.StatementContext$class.mockEntity(Statement.scala:68)
[error] models.postgresqlContext$.mockEntity(postgresqlContext.scala:10)
[error] net.fwbrasil.activate.statement.StatementContext$class.mockEntity(Statement.scala:63)
[error] models.postgresqlContext$.mockEntity(postgresqlContext.scala:10)
[error] net.fwbrasil.activate.statement.query.QueryContext$$anonfun$produceQuery$1.apply(Query.scala:35)
[error] net.fwbrasil.activate.statement.query.QueryContext$$anonfun$produceQuery$1.apply(Query.scala:35)
[error] net.fwbrasil.activate.statement.From$.runAndClearFrom(StatementFrom.scala:38)
[error] net.fwbrasil.activate.statement.query.QueryContext$class.produceQuery(Query.scala:34)
[error] models.postgresqlContext$.produceQuery(postgresqlContext.scala:10)

Entity with list of Strings

I'm trying to make an Entity that has Lists of strings. So I need an EntityForm that receives those lists like this:

val trackerForm = EntityForm[TrackerRevision](_.name -> nonEmptyText,
_.manufacturer -> optional%28text%29,
_.tracking_frequency -> optional%28longNumber%29,
_.device_search_prefix -> list%28text%29,
_.fw_revision -> list%28text%29)

When I do that I receive this error message:

java.lang.InstantiationError: scala.collection.immutable.List
sun.reflect.GeneratedSerializationConstructorAccessor319.newInstance(Unknown Source)
java.lang.reflect.Constructor.newInstance(Constructor.java:513)
org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:56)
org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
net.fwbrasil.activate.util.Reflection$.newInstanceUnitialized(Reflection.scala:57)
net.fwbrasil.activate.util.Reflection$.newInstance(Reflection.scala:51)
net.fwbrasil.activate.statement.StatementMocks$.mock(StatementMocks.scala:81)
net.fwbrasil.activate.statement.StatementMocks$FakeVar.get(StatementMocks.scala:54)
net.fwbrasil.activate.entity.Var.getValue(Var.scala:45)
models.TrackerRevision.device_search_prefix(Tracker.scala:22)
controllers.TrackerController$$anonfun$4.apply(TrackerController.scala:70)
controllers.TrackerController$$anonfun$4.apply(TrackerController.scala:70)
net.fwbrasil.activate.play.EntityForm$$anonfun$1.apply(EntityForm.scala:57)
net.fwbrasil.activate.play.EntityForm$$anonfun$1.apply(EntityForm.scala:57)
scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194)
scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:194)
scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59)
scala.collection.immutable.List.foreach(List.scala:45)
scala.collection.TraversableLike$class.map(TraversableLike.scala:194)
scala.collection.immutable.List.map(List.scala:45)
net.fwbrasil.activate.play.EntityForm$.build(EntityForm.scala:57)
net.fwbrasil.activate.play.EntityForm$.apply(EntityForm.scala:53)
controllers.TrackerController$.(TrackerController.scala:66)
controllers.TrackerController$.(TrackerController.scala)
Routes$$anonfun$routes$1$$anonfun$apply$71$$anonfun$apply$72.apply(routes_routing.scala:524)
Routes$$anonfun$routes$1$$anonfun$apply$71$$anonfun$apply$72.apply(routes_routing.scala:524)
play.core.Router$HandlerInvoker$$anon$4.call(Router.scala:1084)
play.core.Router$Routes$class.invokeHandler(Router.scala:1259)
Routes$.invokeHandler(routes_routing.scala:14)
Routes$$anonfun$routes$1$$anonfun$apply$71.apply(routes_routing.scala:524)
Routes$$anonfun$routes$1$$anonfun$apply$71.apply(routes_routing.scala:524)
play.core.Router$Routes$class.call(Router.scala:1127)
Routes$.call(routes_routing.scala:14)
Routes$$anonfun$routes$1.apply(routes_routing.scala:523)
Routes$$anonfun$routes$1.apply(routes_routing.scala:239)
scala.PartialFunction$$anon$3.apply(PartialFunction.scala:67)
scala.PartialFunction$$anon$3.apply(PartialFunction.scala:66)
play.core.Router$Routes$class.handlerFor(Router.scala:1255)
Routes$.handlerFor(routes_routing.scala:14)
play.api.GlobalSettings$$anonfun$onRouteRequest$1$$anonfun$apply$1.apply(Global.scala:64)
play.api.GlobalSettings$$anonfun$onRouteRequest$1$$anonfun$apply$1.apply(Global.scala:63)
scala.Option.flatMap(Option.scala:146)
play.api.GlobalSettings$$anonfun$onRouteRequest$1.apply(Global.scala:63)
play.api.GlobalSettings$$anonfun$onRouteRequest$1.apply(Global.scala:63)
scala.Option.flatMap(Option.scala:146)
play.api.GlobalSettings$class.onRouteRequest(Global.scala:63)
util.Global$.onRouteRequest(Global.scala:7)
play.core.server.Server$$anonfun$sendHandler$1$1.apply(Server.scala:60)
play.core.server.Server$$anonfun$sendHandler$1$1.apply(Server.scala:59)
scala.Either$RightProjection.map(Either.scala:285)
play.core.server.Server$class.sendHandler$1(Server.scala:59)
play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:89)
play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:88)
scala.Either$RightProjection.flatMap(Either.scala:277)
play.core.server.Server$class.getHandlerFor(Server.scala:88)
play.core.server.NettyServer.getHandlerFor(NettyServer.scala:38)
play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:226)
org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75)
org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:563)
org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:366)
org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:568)
org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:437)
org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75)
org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:563)
org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:558)
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:91)
org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:373)
org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:247)
org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35)
org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102)
org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:680)

Nested entities and JSON deserialization

Not sure if this is an error or I'm misusing the framework. I have an object like such:

class Event(
  val name: String,
  val description: String,
  val subdomain: String,
  val internalId: String,
  val fromDate: DateTime,
  val thruDate: DateTime,
  val singleTerms: immutable.List[String],
  val compoundTerms: immutable.List[String],
  var boundingBoxes: immutable.List[BoundingBox]) extends Entity

Where BoundingBox is an Entity that contains another Entity:

class BoundingBox(val swCorner: GeoData, val neCorner: GeoData) extends Entity 

This is all well and good within the application. My issue is when I try and create an Event from JSON, with something like this:

{
    "name": "Foo",
    "fromDate": "2013-09-01T01:55:10",
    "thruDate": "2013-10-31T01:55:10",
    "singleTerms": [
        "Foo",
        "Bar"
    ],
    "compoundTerms": [
        "foo bar"
    ],
    "boundingBoxes": [
        {
            "swCorner": {
                "latitude": 30.2,
                "longitude": -81.75
            },
            "neCorner": {
                "latitude": 30.37,
                "longitude": -81.45
            }
        }
    ]
}

I get the following exception from Activate Spray Json:

scala.MatchError: ({"swCorner":{"latitude":30.2,"longitude":-81.75},"neCorner":{"latitude":30.37,"longitude":-81.45}},EntityInstanceEntityValue(None)) (of class scala.Tuple2)
    at net.fwbrasil.activate.json.spray.SprayJsonContext$class.net$fwbrasil$activate$json$spray$SprayJsonContext$$fromJsValue(SprayJsonContext.scala:48) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$$anonfun$net$fwbrasil$activate$json$spray$SprayJsonContext$$fromJsValue$6.apply(SprayJsonContext.scala:88) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$$anonfun$net$fwbrasil$activate$json$spray$SprayJsonContext$$fromJsValue$6.apply(SprayJsonContext.scala:88) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:0.12.3]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:0.12.3]
    at scala.collection.immutable.List.foreach(List.scala:318) ~[scala-library.jar:0.12.3]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:0.12.3]
    at scala.collection.AbstractTraversable.map(Traversable.scala:105) ~[scala-library.jar:0.12.3]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$class.net$fwbrasil$activate$json$spray$SprayJsonContext$$fromJsValue(SprayJsonContext.scala:88) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$$anonfun$updateFromJsonObject$3.apply(SprayJsonContext.scala:165) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$$anonfun$updateFromJsonObject$3.apply(SprayJsonContext.scala:161) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:772) ~[scala-library.jar:0.12.3]
    at scala.collection.Iterator$class.foreach(Iterator.scala:727) ~[scala-library.jar:0.12.3]
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157) ~[scala-library.jar:0.12.3]
    at scala.collection.IterableLike$class.foreach(IterableLike.scala:72) ~[scala-library.jar:0.12.3]
    at scala.collection.AbstractIterable.foreach(Iterable.scala:54) ~[scala-library.jar:0.12.3]
    at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:771) ~[scala-library.jar:0.12.3]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$class.updateFromJsonObject(SprayJsonContext.scala:161) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$class.createEntityFromJson(SprayJsonContext.scala:185) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at eventhash.common.persistence.ActivateJsonContext$.createEntityFromJson(ActivateJsonContext.scala:13) ~[classes/:na]
    at net.fwbrasil.activate.json.spray.SprayJsonContext$class.createEntityFromJson(SprayJsonContext.scala:176) ~[activate-spray-json_2.10-1.4-SNAPSHOT.jar:1.4-SNAPSHOT]
    at eventhash.common.persistence.ActivateJsonContext$.createEntityFromJson(ActivateJsonContext.scala:13) ~[classes/:na]
TRUNCATED

I don't think I'm doing anything that spray-json doesn't allow; thanks for looking into this for me.

How to get JPA Entity Manager for Play background processes?

Hi,

I am using JPA with Play 2.0.2 version, any kind of transactions are working fine with action methods.
I am also using some background processes, where I need to work with JPA, I am getting below exception:

Exception in thread "Timer-0" java.lang.RuntimeException: No EntityManager bound to this thread. Try to annotate your action method with @play.db.jpa.Transactional
at play.db.jpa.JPA.em(JPA.java:45)

I am using TimerTask class to run my jobs at background. I also annotated run method with @transactional annotation. But still getting the above exception. Can anybody help me to fix this issue?

Thanks in advance.

  • Nataraj G.

How can I create table on the DB?

I'm playing with Activate and I don't quite understand how to physically create tables in the DB.
Currently I've this class trait which migrate a simple case class:

trait JobStateSchema extends Migration {

  def timestamp = 201301161230L

  def up {
    table[JobState]
      .createTable(
        _.column[JobId]("id"),
        _.column[Long]("transactionTotal"),
        _.column[Long]("transactionFailures"),
        _.column[Long]("snapshotTotal"),
        _.column[Long]("snapshotFailures"))
  }
}

and my JobState is defined elsewhere, this way:

case class JobState(
    override val id: JobId,
    transactionTotal: Long,
    transactionFailures: Long,
    snapshotTotal: Long,
    snapshotFailures: Long) extends Entity

I have this Context:

trait Persistence extends ActivateContext

object PostgreSQL extends Persistence {
  val config = ConfigFactory.load("postgres")

  val storage = new PooledJdbcRelationalStorage {
    val jdbcDriver = config.getString("postgres.driver")
    val user = config.getString("postgres.user")
    val password = config.getString("postgres.pwd")
    val url = config.getString("postgres.dburi")
    val dialect = postgresqlDialect
  }
}

Now, I've created a simple Scala App that should run a transaction and persist the data inside the DB. Correct?

import PostgreSQL._

object MigrateAML extends App {

    transactional {
      val job = JobState("10", 20,20,20,20)
      println(job.id)
    }
}

But I see only a table called "storageversion" inside my DB. How come?

I've tried to use a ManualMigration and explicitly calling "up", but without any success.

@Alias

it is not working in 1.3 version.

Example:

@Alias("foo")
case class Foo(@Alias("foo_name") name: String) extends Entity

Migration

table[Foo]
      .createTable(
      _.column[String]("foo_name")
    )

Table column validation 'ifExists' not working properly on Migrations

The following piece of code causes no update on columns name.

def up = {
table[Usuario].renameColumn("displayName",_.columnString)
.ifExists
}

It looks like something goes wrong with the ifExists option, because since it is removed from the code, the table Usuario has its column 'displayName' updated to '_displayName'.

One might ask "One hundred percent sure that displayName already exists before the migration?" and the answer is YES.

RequiredTransactionException stack trace

Hi,

I wrapped my code with transactional but I still get RequiredTransactionException:

net.fwbrasil.radon.RequiredTransactionException: null
at net.fwbrasil.radon.transaction.TransactionManager.getRequiredActiveTransaction(TransactionManager.scala:39) ~[radon-stm_2.10-1.2-RC4.jar:1.2-RC4]
at net.fwbrasil.radon.ref.Ref.getRequiredTransaction(Ref.scala:61) ~[radon-stm_2.10-1.2-RC4.jar:1.2-RC4]
at net.fwbrasil.radon.ref.Ref.isDestroyed(Ref.scala:130) ~[radon-stm_2.10-1.2-RC4.jar:1.2-RC4]
at net.fwbrasil.activate.entity.Var.isDestroyedSnapshot(Var.scala:62) ~[activate-core_2.10-1.2-RC4.jar:1.2-RC4]
at net.fwbrasil.activate.entity.Entity$class.isDeletedSnapshot(Entity.scala:62) ~[activate-core_2.10-1.2-RC4.jar:1.2-RC4]
at models.Post.isDeletedSnapshot(Post.scala:13) ~[na:na]

How can I find out which line causes the problem and what should I do to avoid this exception?

Thanks

JSR 303 validation support

Can activate support JSR 303 like annotation based validation?
If not how can I plug in the jsr validation into the activate framework?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.