Giter Club home page Giter Club logo

Comments (9)

rktoomey avatar rktoomey commented on July 25, 2024

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.

rktoomey avatar rktoomey commented on July 25, 2024

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.

hajdamak avatar hajdamak commented on July 25, 2024

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.

rktoomey avatar rktoomey commented on July 25, 2024

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.

hajdamak avatar hajdamak commented on July 25, 2024

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.

rktoomey avatar rktoomey commented on July 25, 2024

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.

hajdamak avatar hajdamak commented on July 25, 2024

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.

rktoomey avatar rktoomey commented on July 25, 2024

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.

hajdamak avatar hajdamak commented on July 25, 2024

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)

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.