Comments (9)
I created a spec showing this fails with pendingUntilFixed.
As a workaround: declare your case classes outside of the trait - in this example, Employee lives outside of ModelCtx and must be imported in TestApp. Then use grater[Employee] and that should work.
from salat.
Rafał , just out of interest, are you using a web framework of some type? I'm not familiar with this pattern and wanted to see where it fits in to your usage case, and maybe test it out with this framework directly and offer support for it if I can.
from salat.
This structure is a result of using cake pattern to achieve dependency injection:
http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf
http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html
I am using Unfiltered as web framework but it does not enforce such a structure.
from salat.
Won't fix. Due to how Scala handles a case class nested in another class, it creates a chicken and egg problem where is it not possible to get the companion object and class the grater needs in a usable form.
For instance,
scala> val g = grater[SomeTrait#NestedCaseClassInATrait]
g: com.novus.salat.Grater[com.novus.salat.test.model.SomeTrait#NestedCaseClassInATrait] = Grater(class com.novus.salat.test.model.SomeTrait$NestedCaseClassInATrait @ com.novus.salat.global.package$$anon$1@7cec59b)
Note that the sole constructor expects a reference to the outer trait:
scala> g.clazz.getConstructors.head
res4: java.lang.reflect.Constructor[_] = public com.novus.salat.test.model.SomeTrait$NestedCaseClassInATrait(com.novus.salat.test.model.SomeTrait,java.lang.String,scala.Option,scala.Option)
Meanwhile, the innter class companion class requires an actual backref to outer trait:
scala> val outer = g.clazz.companionClass.getDeclaredFields.head
outer: java.lang.reflect.Field = private final com.novus.salat.test.model.SomeTrait com.novus.salat.test.model.SomeTrait$NestedCaseClassInATrait$.$outer
And finally, the apply looks promising but it is bad candy. You can't actually invoke it - you have to use the one that requires the backref we can't provide:
scala> g.companionClass.getMethods.filter(_.getName == "apply").head
res15: java.lang.reflect.Method = public com.novus.salat.test.model.SomeTrait$NestedCaseClassInATrait com.novus.salat.test.model.SomeTrait$NestedCaseClassInATrait$.apply(java.lang.String,scala.Option,scala.Option)
Sigh.
scala> g.companionClass.newInstance
java.lang.InstantiationException: com.novus.salat.test.model.SomeTrait$NestedCaseClassInATrait$
Sorry, Rafał, I tried! It's just not possible for us to support this pattern verbatim. However, if you declare your case classes without nesting them in an outer class, you can use Salat.
from salat.
Thanks for your efforts to solve it. Fortunately this is not that problematic to have case classes outside of the trait. The only missed feature with this approach is that one won't be able to reference injected classes from entity case class methods (no DI inside entity classes).
from salat.
Yes, I feel very bad about that. I haven't abandoned the topic 100%: I was considering making a post of some type, maybe StackOverflow, asking how serialization back to object could ever be expected to work in Cake pattern without some heavy duty Java reflection given the constraints Scala imposed on inner classes.
from salat.
How about using copy method on case class. User of the Salat would provide some instance of the case class and grater would use copy operation on it to generate new instance. It is not very elegant but maybe this will allow to avoid this circular dependency. What do you think?
from salat.
Alas, our problem is that we are de-serializing from something else back to a case class, and don't have a handy instance of the case class hanging around... :) That's what we're trying and failing to get from the companion class and companion object.
By the end of the weekend I will try to write up a wiki page explaining the problem in more detail and make a posting to the Salat google group asking for help to find a solution.
from salat.
But the idea is that client will provide this handy instance. Grater API would for example work like that:
val fakeEmployee = Employee("Frank", e)
grater(fakeEmployee).asObject(dboToTransform)
from salat.
Related Issues (20)
- Custom TypeHint strategy for JSON HOT 2
- Unable to serialize case class hierarchy HOT 3
- mongo connection leak - re-use one mongo connection for each test DAO to reduce connection footprint. HOT 2
- Update Casbah to 2.8.2 in Salat 1.10.x to support connecting to Mongo 3.x server. HOT 16
- Play Salat HOT 4
- Project status update? HOT 23
- java.lang.ClassCastException when deserializing from Salat in context of akka runtime. HOT 4
- Error with reason "Very strange!" - GRATER GLITCH HOT 2
- Upgrade to sbt 0.13.12
- Release Salat 1.10 HOT 1
- JSON data can deserialize into collections containing data not matching the container generic type.
- More specific error class for Grater errors: SalatDeserializationException
- Release 1.11.x with Casbah 3.1.1 support (but not Scala 2.12) HOT 18
- Will this work with the latest Casbah 3.1.1? HOT 1
- SalatDAO support for collections HOT 7
- Scala 2.12 HOT 8
- Optional field in MongoDBObject with null value causing MatchError HOT 11
- Custom Transformers never get applied to case classes HOT 9
- Case class not serialising in order HOT 3
- Support for Mongo 3.6+ HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from salat.