This sounds interesting... can you give an example of how this might 
work in Scala?

Chas.

David Pollak wrote:
> Okay, this is going to sound wacky (and a bit Haskell Mondadish)... but...
> 
> What about not mutating the objects themselves... what about keeping a 
> chain of mutator functions... in effect a change log.  When you're all 
> ready to commit the changes to the RDBMS, you open a session, apply the 
> change functions, and commit the transaction?
> 
> On Wed, Jan 14, 2009 at 11:47 PM, Charles F. Munat <[email protected] 
> <mailto:[email protected]>> wrote:
> 
> 
>     Exactly. Unfortunately, I'm not sure that this is even possible.
>     Hibernate detaches objects, and, if I've understood it correctly, it
>     might even be possible for an object to have multiple persistence
>     contexts. So a simple link back to the context isn't going to work.
> 
>     But there ought to be some way to create a sort of persistence context
>     from one entity that would allow it to access other entities. Then
>     again, there may be constraints (e.g. transactional or otherwise) that
>     make this difficult or impossible. I think the problem is with the way
>     Hibernate is structured. ActiveRecord is more SQL based, so it's quite
>     easy to do this sort of thing in ActiveRecord.
> 
>     With Mapper as a sort of ActiveRecord-like system, maybe it would be
>     possible in Mapper. If I get time I'll have to think about it. Someone
>     else could probably answer off the top of their head.
> 
>     Chas.
> 
>     Kris Nuttycombe wrote:
>      >
>      >
>      > On Wed, Jan 14, 2009 at 6:30 PM, Charles F. Munat <[email protected]
>     <mailto:[email protected]>
>      > <mailto:[email protected] <mailto:[email protected]>>> wrote:
>      >
>      >
>      >     What I'm trying to do is implement list and tree-like
>     behavior via a
>      >     trait.
>      >
>      >     I want to create an object, say a Whatsit. And then I want to
>     be able to
>      >     say that Whatsits have list-like behavior by mixing in an
>     ActsAsList
>      >     trait (similar to the way Rails does it).
>      >
>      >     so my class might be
>      >
>      >     class Whatsit extends ActsAsList...
>      >
>      >     And this trait would automatically add attributes and methods
>     to permit
>      >     list-like behavior, for example:
>      >
>      >     def moveUp
>      >     def moveDown
>      >     def moveToTop
>      >     def moveToBottom
>      >     def isFirst
>      >     def isLast
>      >
>      >     and so on. So then when I created and persisted a new
>     Whatsit, it would
>      >     automatically be added at the end of the list. Then I could call
>      >     moveToBefore(other) to position it right before "other" in
>     the list.
>      >
>      >     Same idea with trees, etc.
>      >
>      >     I use lists and trees a lot, so I'd love to be able to just
>     add a trait.
>      >
>      >     The obvious way to do this in Java is through a DAO, but I've
>     avoided
>      >     all that boilerplate in Scala and would like to continue to
>     do so.
>      >
>      >     This is one area, IMO, that Record/Mapper could beat the
>     pants off of
>      >     Hibernate. Maybe someone has already done this in Hibernate,
>     but I can't
>      >     find it.
>      >
>      >     Chas.
>      >
>      >
>      > Ah, I see the problem you're talking about. You need some
>     reference to
>      > the persistence context that you can obtain from the entity itself so
>      > that your trait can make the necessary updates to the other
>     entities in
>      > the list, given that the individual entities don't have direct
>      > relationships to one another.
>      >
>      > I've often wished that Hibernate would provide a static method that
>      > could take a Hibernate-managed object and give you back the
>     persistence
>      > context to which it's bound. Seems like something that a lot of
>      > applications could make use of.
>      >
>      > Kris
>      >
>      >
>      >     Kris Nuttycombe wrote:
>      >      > On Wed, Jan 14, 2009 at 5:02 PM, Charles F. Munat
>     <[email protected] <mailto:[email protected]>
>      >     <mailto:[email protected] <mailto:[email protected]>>
>      >      > <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>> wrote:
>      >      >
>      >      >
>      >      >     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.
>      >      >
>      >      >
>      >      > What sort of manipulation are you interested in? If you
>     have your
>      >      > cascades set up correctly, you usually don't need to
>     involve an
>      >      > EntityManager - the persistence layer gets updated
>     correctly when the
>      >      > transaction associated with the request completes. The
>     only bit
>      >     I'm not
>      >      > sure about with that is the behavior of removes.
>      >      >
>      >      > Kris
>      >      >
>      >      >
>      >      >     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
>      >     <[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >      > <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>> 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
>      >      >     <[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>
>      >      >      >      > <mailto:[email protected]
>     <mailto:[email protected]> <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>>> 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
>      >      >      >     <[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>
>      >      >      >      >     <mailto:[email protected]
>     <mailto:[email protected]> <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>>
>      >      >      >      >      > <mailto:[email protected]
>     <mailto:[email protected]>
>      >     <mailto:[email protected] <mailto:[email protected]>>
>     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>
>      >      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>
>      >      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>
>      >     <mailto:[email protected] <mailto:[email protected]>
>     <mailto:[email protected] <mailto:[email protected]>>>>>>> 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>
>      >      >      >      >     <http://mike.sr> <http://mike.sr>
>      >      >      >      >      >      > <http://mike.sr>@gmail.com
>     <http://gmail.com>
>      >     <http://gmail.com>
>      >      >     <http://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
>      >      >      >      >      >      >
>      >      >      >      >      >      >
>      >      >      >      >      >      >
>      >      >      >      >      >      >
>      >      >      >      >      >      > >
>      >      >      >      >      >
>      >      >      >      >      >
>      >      >      >      >      >
>      >      >      >      >      >
>      >      >      >      >      > >
>      >      >      >      >
>      >      >      >      >
>      >      >      >      >
>      >      >      >      >
>      >      >      >      > >
>      >      >      >
>      >      >      >
>      >      >      >
>      >      >      >
>      >      >      > >
>      >      >
>      >      >
>      >      >
>      >      >
>      >      > >
>      >
>      >
>      >
>      >
>      > >
> 
> 
> 
> 
> 
> -- 
> Lift, the simply functional web framework http://liftweb.net
> Collaborative Task Management http://much4.us
> Follow me: http://twitter.com/dpp
> Git some: http://github.com/dpp
> 
> > 

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

Reply via email to