Excellent. Your reasons for using POJOs make perfect sense, and none of 
them have any relevance for me, which means that for my apps -- which 
are relatively pure Scala -- I'm on the right track.

Thanks again. This really helps.

Now if I could just get Hibernate to permit one entity to manipulate 
another without going through an EntityManager, I'd be in heaven.

Chas.

Kris Nuttycombe wrote:
> I'm not sure it's that thorough; it's just a copy/paste from my app. :)
> 
> The reason that the entities are POJOs is simple; the Lift app is simply 
> a small internal administrative interface for a much larger Java EE 
> application. I've toyed with the possibility of porting as much of the 
> main app as possible to Scala, but there's just no time to do it. Also, 
> I really love having good refactoring support in the IDE, and it's just 
> not there yet for scala alone, much less hybrid scala/java projects.
> 
> Kris
> 
> On Wed, Jan 14, 2009 at 3:05 PM, Charles F. Munat <c...@munat.com 
> <mailto:c...@munat.com>> wrote:
> 
> 
>     Kris,
> 
>     Thank you much for this very thorough exegesis. I'll study it and will
>     try to wrap my tiny brain around it. I really appreciate the effort you
>     put into it.
> 
>     One question... why did you choose to implement the entities as POJOs
>     instead of as Scala objects? I've been working with the latter without
>     too much difficulty, and I'd like to avoid writing Java as much as
>     possible. Is there some advantage to using POJOs?
> 
>     Chas.
> 
>     Kris Nuttycombe wrote:
>      > Hi, Chas,
>      >
>      > Sorry it's taken me so long to respond to this - I've been pretty
>     buried
>      > for the past week.
>      >
>      > Here's an example of what I'm doing:
>      >
>      >
>      > trait Binding {
>      >     def apply(xhtml : NodeSeq) : NodeSeq = xhtml
>      > }
>      >
>      > trait EntityBinding[+T] extends Binding {
>      >     def entity : T
>      > }
>      >
>      > trait SubscriptionEventBinding extends
>     EntityBinding[SubscriptionEvent] {
>      >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
>      >         val transTemplate = chooseTemplate("event",
>     "transactions", xhtml)
>      >
>      >         bind("event", super.apply(xhtml),
>      >              "scheduleDate" -> h(entity.getScheduleDate),
>      >              "transactions" ->
>      > Group(entity.getTransactions.toSeq.flatMap(_(transTemplate)))
>      >         )
>      >     }
>      > }
>      >
>      > trait BillingEventBinding extends
>      > EntityBinding[SubscriptionBillingEvent] with
>     SubscriptionEventBinding {
>      >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
>      >         bind("event", super.apply(xhtml),
>      >              "detail" -> <span>Charges: ${entity.getCharge};
>     Discount:
>      > ${entity.getDiscount}</span>,
>      >              "type" -> h("Billing"))
>      >     }
>      > }
>      >
>      > trait CancellationEventBinding extends
>      > EntityBinding[SubscriptionCancellationEvent] with
>     SubscriptionEventBinding {
>      >     abstract override def apply(xhtml : NodeSeq) : NodeSeq = {
>      >         bind("event", super.apply(xhtml),
>      >              "detail" -> <div>Reason: {entity.getReason}<br/>Final
>      > Balance: {entity.getFinalBalance}</div>,
>      >              "type" -> h("Cancellation"))
>      >     }
>      > }
>      >
>      > Then, in the appropriate scope, I import the correct implicit:
>      >
>      >     implicit def entityToEventBinding(e : SubscriptionEvent) :
>     Binding = {
>      >         e match {
>      >             case b : SubscriptionBillingEvent      => new
>      > BillingEventBinding        { override val entity = b }
>      >             case c : SubscriptionCancellationEvent => new
>      > CancellationEventBinding   { override val entity = c }
>      >             case _ => throw new IllegalStateException("Unbindable
>     event
>      > " + e.getClass + " (" + e + ")")
>      >         }
>      >     }
>      >
>      > All of the entity classes are JPA entities implemented in Java. If I
>      > have a different set of bindings for a different context, I simply
>      > create a separate trait. The nice thing about this approach is
>     that the
>      > traits are stackable over an inheritance hierarchy, as above.
>      >
>      > With this in place, I can just treat my entity as a binding
>     context on
>      > its own:
>      >
>      >   object Subscriptions {
>      >     object current extends SessionVar[Box[Subscription]](Empty)
>      >   }
>      >
>      > ... stuff that populates the SessionVar
>      >
>      >   def events(xhtml : NodeSeq) : NodeSeq = {
>      >
>      >
>     
> Subscriptions.current.is.map(_.events.toSeq.flatMap(_(xhtml))).openOr(h("No
>      > subscription to display events for."))
>      >   }
>      >
>      >
>      > Kris
>      >
>      >
>      > On Fri, Jan 9, 2009 at 5:29 PM, Charles F. Munat <c...@munat.com
>     <mailto:c...@munat.com>
>      > <mailto:c...@munat.com <mailto:c...@munat.com>>> wrote:
>      >
>      >
>      >     That sounds kinda smart. Is there any chance you could post
>     some example
>      >     code?
>      >
>      >     Chas.
>      >
>      >     Kris Nuttycombe wrote:
>      >      > Oh, I'm not complaining about the way User is handled - my
>      >     response was
>      >      > more about the general hate towards MVC upthread. Having a
>     sensible
>      >      > default for a standard use case is great, even when I'll
>     probably
>      >     never
>      >      > use the default.
>      >      >
>      >      > In my Lift app, my shortcut to different renderings (well,
>     different
>      >      > bindings, really) is to keep all the binding logic for a
>     specific
>      >     case
>      >      > in a trait and have an implicit conversion from my model
>     to the
>      >      > appropriate trait in the relevant scope. You still have to
>     do the
>      >     work,
>      >      > but it makes the bindings a lot easier to reuse.
>      >      >
>      >      > Kris
>      >      >
>      >      > On Fri, Jan 9, 2009 at 4:46 PM, Charles F. Munat
>     <c...@munat.com <mailto:c...@munat.com>
>      >     <mailto:c...@munat.com <mailto:c...@munat.com>>
>      >      > <mailto:c...@munat.com <mailto:c...@munat.com>
>     <mailto:c...@munat.com <mailto:c...@munat.com>>>> wrote:
>      >      >
>      >      >
>      >      >     I don't see how you're any worse off if the model can
>     render
>      >     itself in
>      >      >     one way. And if that way is a common
>     standards-compliant way,
>      >     such as
>      >      >     rendering to XML, and you include semantic
>     information, then
>      >     you can
>      >      >     layer any other layers you want on top to do the
>     mapping to
>      >     the 30
>      >      >     different contexts.
>      >      >
>      >      >     Saying that an object should know how to render itself
>     to some
>      >      >     universally recognized format is not the same as
>     saying that
>      >     that solves
>      >      >     all rendering issues.
>      >      >
>      >      >     Is there some shortcut to 30 different renderings that I'm
>      >     missing, or
>      >      >     do you have to do the work either way?
>      >      >
>      >      >     Chas.
>      >      >
>      >      >     Kris Nuttycombe wrote:
>      >      >      > If you want to render a model 30 different ways in 30
>      >     different
>      >      >      > contexts, it kind of sucks though, doesn't it?
>      >      >      >
>      >      >      > Or what if, shock horror, you don't know how the
>     eventual
>      >     system is
>      >      >      > going to want to render the model (i.e., the person
>     doing the
>      >      >     rendering
>      >      >      > won't be able to change the model code.) Not too
>     uncommon, I
>      >      >     don't think...
>      >      >      >
>      >      >      > Kris
>      >      >      >
>      >      >      > On Sun, Jan 4, 2009 at 9:58 AM, Michael <mike.sr
>     <http://mike.sr>
>      >     <http://mike.sr> <http://mike.sr>
>      >      >      > <http://mike.sr>@gmail.com <http://gmail.com>
>     <http://gmail.com>
>      >     <http://gmail.com> <http://gmail.com>>
>      >      >     wrote:
>      >      >      >
>      >      >      >
>      >      >      >      > Also I was looking at the sample model
>     source code
>      >     (User,
>      >      >     ProtoUser)
>      >      >      >      > and saw presentation logic mixed in it.
>     Shouldn't the
>      >      >     business and
>      >      >      >      > model logic be kept separated from the
>     presentation
>      >     logic
>      >      >     or is there
>      >      >      >      > a Lift strategy it?
>      >      >      >
>      >      >      >     Hmm, a model that can render itself ... That sounds
>      >     like this
>      >      >     crazy
>      >      >      >     paradigm called object-oriented programming.
>     Some radicals
>      >      >     say it has
>      >      >      >     some advantages over the more procedural style
>     of MVC.
>      >      >      >
>      >      >      >     -- Michael
>      >      >      >
>      >      >      >
>      >      >      >
>      >      >      >
>      >      >      > >
>      >      >
>      >      >
>      >      >
>      >      >
>      >      > >
>      >
>      >
>      >
>      >
>      > >
> 
> 
> 
> 
> > 

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Lift" group.
To post to this group, send email to liftweb@googlegroups.com
To unsubscribe from this group, send email to 
liftweb+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to