[Lift] Re: One further: JPA + JTA + Lift

2008-09-10 Thread Kris Nuttycombe

The principal reason I'm using Hibernate is because the base JPA
unfortunately doesn't provide support for non-standard type
persistence, and so a few of my entities are annotated with @Type in
order to use custom mappings for some of the org.joda.time classes
(the Order object in question being one of them.)

I've now got debug logging working; here is one interesting bit; after
adding a logging check to see whether the EntityManager is open:

  def list(xhtml: NodeSeq) : NodeSeq = {
Log.info(Entity manager is open:  + em.isOpen().toString())
val orders = em.createQuery(FROM
Order).getResultList().asInstanceOf[java.util.List[Order]]

I get:

INFO  lift - Entity manager is open: true
DEBUG impl.SessionImpl - opened session at timestamp: 12209812983
DEBUG ejb.AbstractEntityManagerImpl - Looking for a JTA transaction to join
DEBUG ejb.AbstractEntityManagerImpl - No JTA transaction found

Since there's no JTA transaction found, I'm suspecting that Hibernate
is creating its own session to use for the fetch, and is closing it
afterward. The failure to find a JTA transaction is a bit telling,
though - I wonder if in the standard Glassfish stack, JTA transactions
are established in a servlet filter that's not being used with Lift -
that Lift does request handling too far upstream or something.

DEBUG ast.QueryTranslatorImpl - parse() - HQL: FROM
com.gaiam.gcsi.entities.subscription.Order
DEBUG ast.HqlParser - weakKeywords() : new LT(1) token -
[Order,120 previously: 41,line=1,col=43,possibleID=true]
DEBUG ast.AST - --- HQL AST ---
 \-[QUERY] 'query'
\-[SELECT_FROM] 'SELECT_FROM'
   \-[FROM] 'FROM'
  \-[RANGE] 'RANGE'
 \-[DOT] '.'
+-[DOT] '.'
|  +-[DOT] '.'
|  |  +-[DOT] '.'
|  |  |  +-[DOT] '.'
|  |  |  |  +-[IDENT] 'com'
|  |  |  |  \-[IDENT] 'gaiam'
|  |  |  \-[IDENT] 'gcsi'
|  |  \-[IDENT] 'entities'
|  \-[IDENT] 'subscription'
\-[IDENT] 'Order'

DEBUG ast.ErrorCounter - throwQueryException() : no errors
DEBUG antlr.HqlSqlBaseWalker - select  begin [level=1, statement=select]
DEBUG tree.FromElement - FromClause{level=1} :
com.gaiam.gcsi.entities.subscription.Order (no alias) - order0_
DEBUG antlr.HqlSqlBaseWalker - select : finishing up [level=1, statement=select]
DEBUG ast.HqlSqlWalker - processQuery() :  ( SELECT (
FromClause{level=1} orders order0_ ) )
DEBUG ast.HqlSqlWalker - Derived SELECT clause created.
DEBUG util.JoinProcessor - Using FROM fragment [orders order0_]
DEBUG antlr.HqlSqlBaseWalker - select  end [level=1, statement=select]
DEBUG ast.AST - --- SQL AST ---
 \-[SELECT] QueryNode: 'SELECT'  querySpaces (orders)
+-[SELECT_CLAUSE] SelectClause: '{derived select clause}'
|  +-[SELECT_EXPR] SelectExpressionImpl: 'order0_.id as id506_'
{FromElement{explicit,not a collection join,not a fetch join,fetch
non-lazy 
properties,classAlias=null,role=null,tableName=orders,tableAlias=order0_,origin=null,colums={,className=com.gaiam.gcsi.entities.subscription.Order}}}
|  \-[SQL_TOKEN] SqlFragment: 'order0_.uuid as uuid506_,
order0_.affiliate_id as affiliate5_506_, order0_.order_date as
order3_506_, order0_.payment_source_id as payment6_506_,
order0_.shipping_address_id as shipping7_506_, order0_.source_id as
source8_506_, order0_.state as state506_, order0_.user_id as
user9_506_'
\-[FROM] FromClause: 'FROM' FromClause{level=1,
fromElementCounter=1, fromElements=1, fromElementByClassAlias=[],
fromElementByTableAlias=[order0_], fromElementsByPath=[],
collectionJoinFromElementsByPath=[], impliedElements=[]}
   \-[FROM_FRAGMENT] FromElement: 'orders order0_'
FromElement{explicit,not a collection join,not a fetch join,fetch
non-lazy 
properties,classAlias=null,role=null,tableName=orders,tableAlias=order0_,origin=null,colums={,className=com.gaiam.gcsi.entities.subscription.Order}}
DEBUG ast.ErrorCounter - throwQueryException() : no errors
DEBUG ast.QueryTranslatorImpl - HQL: FROM
com.gaiam.gcsi.entities.subscription.Order
DEBUG ast.QueryTranslatorImpl - SQL: select order0_.id as id506_,
order0_.uuid as uuid506_, order0_.affiliate_id as affiliate5_506_,
order0_.order_date as order3_506_, order0_.payment_source_id as
payment6_506_, order0_.shipping_address_id as shipping7_506_,
order0_.source_id as source8_506_, order0_.state as state506_,
order0_.user_id as user9_506_ from orders order0_
DEBUG ast.ErrorCounter - throwQueryException() : no errors
DEBUG jdbc.AbstractBatcher - about to open PreparedStatement (open
PreparedStatements: 0, globally: 0)
DEBUG jdbc.ConnectionManager - opening JDBC connection
DEBUG hibernate.SQL - select order0_.id as id506_, order0_.uuid as
uuid506_, order0_.affiliate_id as affiliate5_506_, order0_.order_date
as order3_506_, order0_.payment_source_id as payment6_506_,
order0_.shipping_address_id as shipping7_506_, order0_.source_id as
source8_506_, order0_.state as state506_, 

[Lift] Re: JPA w/Scala

2008-09-10 Thread Oliver
Hi Derek,

this is looking good

On Wed, Sep 10, 2008 at 2:55 AM, Derek Chen-Becker [EMAIL PROTECTED]wrote:

 OK, the code is merged in and the latest version is attached. I made a few
 minor modifications to the JPA code that Oliver sent:

 1. I made the openEM and closeEM methods abstract and protected. The idea
 is that the JPA class shouldn't be tied to the way the user wants to access
 JPA. Rather, when they implement the JPA class they can provide their own
 hooks to do direct access, IoC, or JNDI, etc.

 2. I added a convenience method for createNamedQuery so that you can pass
 parameters in when you create the query. A very minor change but it saves a
 little typing when you use it a lot.


I like this, it saves typing and reads a lot better



 I've also changed the module naming per Oliver's suggestion. I'll test
 against the other DBs this afternoon, but so far I've had no issues with
 HSQLDB.


I've also tested it against SQL Server 2000 and it runs without any problems
(unfortunately, I don't have SQL Server 2005 or later, to test against)



 Derek


 On Tue, Sep 9, 2008 at 8:35 AM, Derek Chen-Becker [EMAIL PROTECTED]wrote:

 Looks like I missed a lot in the two days I was gone :). I'm going to look
 at Oliver's code and merge it. As for Tim's problem with the insertions, the
 AUTO ID generation should usually just work. I don't have a SQL Server
 instance to try it out on, but after I merge the code I'll test it again
 with HSQL, PostgreSQL and MySQL to make sure that it works there. If so, it
 may be something specific to the SQL Server dialect.

 Derek


 On Tue, Sep 9, 2008 at 5:09 AM, Oliver Lambert [EMAIL PROTECTED] wrote:



 On 09/09/2008, at 7:47 PM, Tim Perrett wrote:

 
  I agree - its strange and not what we would expect.
 
  What version of SQL server are you running? Im using 2005 Enterprise
  here...
 
 I think thats what they are using at my company


  Its just a really strange thing, the 100 is always ignored... I think
  it just needs a 2nd parameter there, even if its going to ignore it.
  Thats certainly what it looks like from the SQL thats being run
  anyway. I would have thought the GenerationType.IDENTITY would mean
  that it knows not to use it in SQL inserts/updates, but obviously not.
 
 I assume that you have run a simple unit test to do an insert with
 persist e.g.
   def testOK = {

 val na = new Author()
 na.name = HELLO THERE!
 Model.persist(na)

 val authors = Model.createNamedQuery[Author]
 (findAllAuthors).getResultList()

  authors.foreach(author = {
 println(name: +author.name)
 author.books.foreach(book = println(   title: +book.title))
   })
   }

 If you are still having problems, mvn clean your project, zip it up
 and mail it to me - I'll run it tomorrow morning, when I get to work

 Oliver


  Cheers
 
  Tim
  






 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: JPA w/Scala (and hibernate validator)

2008-09-10 Thread Tim Perrett

Out of interest, I tried playing around with hibernate-validator on
this demo to see if it works, and (as you can see below), it doesnt.

Any ideas why its doing this?

Looking at the compiled bytecode, its trying to invoke the synthesized
method name_$eq(String x$1), and for some reason, failing to call it
properly.

Anyone else's input would be interesting :)

Cheers

Tim



---
Test set: com.foo.jpaweb.model.TestJPAWeb
---
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.598
sec  FAILURE!
save_stuff(com.foo.jpaweb.model.TestJPAWeb)  Time elapsed: 1.554 sec
 ERROR!
java.lang.IllegalStateException: Could not get property value
at
org.hibernate.validator.ClassValidator.getMemberValue(ClassValidator.java:
537)
at
org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:
383)
at
org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:
351)
at
org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:
139)
at
org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:
172)
at
org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:
119)
at
org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:
42)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at
org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:
298)
at
org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:
181)
at
org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:
107)
at
org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:
49)
at
org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:
131)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:
87)
at
org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:
38)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
at
org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:
213)
at com.foo.jpaweb.model.TestJPAWeb.save_stuff(TestJPAWeb.scala:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at
org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:
79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:
77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at
org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:
88)
at
org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:
51)
at org.junit.internal.runners.JUnit4ClassRunner
$1.run(JUnit4ClassRunner.java:44)
at
org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:
27)
at
org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:
37)
at
org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:
42)
at
org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:
62)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:
140)
at
org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:
127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
at java.lang.reflect.Method.invoke(Method.java:585)
at
org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:
338)
at

[Lift] Re: JPA w/Scala (and hibernate validator)

2008-09-10 Thread Viktor Klang
Or just write a PropertyAccessor implementation for Scala vars?
That should do the trick.

Cheers,
Viktor

On Wed, Sep 10, 2008 at 3:22 PM, Derek Chen-Becker [EMAIL PROTECTED]wrote:

 Two lines lower it looks like it's trying to fetch the value
 (ClassValidator.getMemberValue), but name_$eq is the setter for a value, not
 the getter. That's probably why it's coming up with the error wrong number
 of arguments. You might try adding an explicit getter for the property
 you want to validate and put the annotation there to see if that works. The
 @BeanProperty Scala annotation might be enough to force the use ofr get/set
 by the Validator framework. Just a guess at this point.

 Derek


 On Wed, Sep 10, 2008 at 3:47 AM, Tim Perrett [EMAIL PROTECTED] wrote:


 Out of interest, I tried playing around with hibernate-validator on
 this demo to see if it works, and (as you can see below), it doesnt.

 Any ideas why its doing this?

 Looking at the compiled bytecode, its trying to invoke the synthesized
 method name_$eq(String x$1), and for some reason, failing to call it
 properly.

 Anyone else's input would be interesting :)

 Cheers

 Tim




 ---
 Test set: com.foo.jpaweb.model.TestJPAWeb

 ---
 Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 1.598
 sec  FAILURE!
 save_stuff(com.foo.jpaweb.model.TestJPAWeb)  Time elapsed: 1.554 sec
  ERROR!
 java.lang.IllegalStateException: Could not get property value
at
 org.hibernate.validator.ClassValidator.getMemberValue(ClassValidator.java:
 537)
at

 org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:
 383)
at

 org.hibernate.validator.ClassValidator.getInvalidValues(ClassValidator.java:
 351)
at

 org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:
 139)
at

 org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:
 172)
at

 org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:
 119)
at

 org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:
 42)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:250)
at

 org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:
 298)
at

 org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:
 181)
at

 org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:
 107)
at

 org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:
 49)
at

 org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:
 131)
at

 org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:
 87)
at

 org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:
 38)
at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:618)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:592)
at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:596)
at

 org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:
 213)
at com.foo.jpaweb.model.TestJPAWeb.save_stuff(TestJPAWeb.scala:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
 39)
at

 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
 25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at
 org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:
 98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:
 79)
at

 org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:
 87)
at
 org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:
 77)
at
 org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at

 org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:
 88)
at

 org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:
 51)
at org.junit.internal.runners.JUnit4ClassRunner
 $1.run(JUnit4ClassRunner.java:44)
at
 org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:
 27)
at
 org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:
 37)
at
 

[Lift] Re: One further: JPA + JTA + Lift

2008-09-10 Thread Kris Nuttycombe

That possibility had occurred to me. Perhaps the best thing is just to
create a separate object for the persistence context that defines both
persistence  transaction operations. You'd then have implementations
for both JTA and RESOURCE_LOCAL type persistence units and store that
in the RequestVar instead. The JTA version would ensure that the
transaction is disposed properly since in JTA you don't actually need
to do anything with the EntityManager in the cleanup hook.
ScalaEntityManager could just become a wrapper like ScalaQuery instead
of it being coupled to the whole request lifecycle.

Kris

On Wed, Sep 10, 2008 at 1:09 PM, Derek Chen-Becker
[EMAIL PROTECTED] wrote:
 I'd be a little concerned about possible race conditions. I don't know
 enough about the underlying handling of the RequestVar lifecycle, but I
 wonder if the transaction RequestVar could get tossed before the EM
 RequestVar (which calls closeEM). You might want to make it a pure
 ThreadLocal to avoid running into any strangeness, although I hope there's a
 cleaner way to do all of this.

 Derek


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: One further: JPA + JTA + Lift

2008-09-10 Thread Derek Chen-Becker
Thanks for pointing that out. I usually use JTA-enabled datasources so I
don't muck around with UserTransaction directly that much.

Derek

On Wed, Sep 10, 2008 at 2:23 PM, Martin Ellis [EMAIL PROTECTED] wrote:


 On Wed, Sep 10, 2008 at 4:27 PM, Kris Nuttycombe
 [EMAIL PROTECTED] wrote:
  The only question I have is thread safety - it doesn't seem
  like I should really be using a variable on the singleton to store the
  transaction; should I instead be creating a separate RequestVar to
  hold it?

 It is thread safe to use a singleton - in fact, it's what Sun do in
 the code that accompanies the Java EE Tutorial...

 web/books/src/main/java/com/sun/books/listeners/ContextListener.java:

 public final class ContextListener implements ServletContextListener {
@PersistenceUnit
private EntityManagerFactory emf;
private ServletContext context = null;
@Resource
private UserTransaction utx;

public void contextInitialized(ServletContextEvent event) {
context = event.getServletContext();

try {
context.setAttribute(emf, emf);
Globals.UTX = utx;


 ... where Globals is defined as:

 public class Globals {
public static UserTransaction UTX;
 }


 Hence, using val instead of def should be fine.

 The begin() and commit() javadoc on UserTransaction:
 Create a new transaction and associate it with the current thread.
 Complete the transaction associated with the current thread. When
 this method completes, the thread is no longer associated with a
 transaction.

 The transaction is associated with the thread that called begin()
 'internally', so there's no need to associate it with a thread
 manually.

 See also:
 http://java.sun.com/javaee/5/docs/tutorial/doc/bnafo.html

 Martin

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Template questions

2008-09-10 Thread Kris Nuttycombe

Man, I really wish I understood the Scala type system better.

  def list(xhtml : NodeSeq) : NodeSeq = {
val orders = EM.createQuery[Order](FROM Order).getResultList
orders.flatMap(order =
  bind(order, xhtml,
   id -- Text(order.getId.toString),
   uuid -- Text(order.getUuid.toString),
   items -- bindItems((xhtml \\ items).first.child,
order.getItems))
)
  }

  private def bindItems(xhtml : NodeSeq, items :
java.util.Collection[Item]) : NodeSeq = {
items.flatMap(item =
  bind(item, xhtml,
   name -- Text(item.getName)))
  }

[WARNING] 
/home/knuttycombe/work/gcsi/gcsi-admin/src/main/scala/com/gaiam/gcsi/snippet/Orders.scala:33:
error: type mismatch;
[WARNING]  found   : Iterable[scala.xml.Node]
[WARNING]  required: scala.xml.NodeSeq
[WARNING] items.flatMap(item =
[WARNING]  ^
[WARNING] one error found

That's the only error, too; the list function compiles just fine.
I've tried making that items.flatMap[NodeSeq], adding an explicit cast
.asInstanceOf[NodeSeq] to the results of the binding, and split
bindItems out into a separate function just to try to make things look
as much the same as possible. WTF?

Kris

On Wed, Sep 10, 2008 at 2:28 PM, Derek Chen-Becker
[EMAIL PROTECTED] wrote:
 Sorry, forgot about that. You might be able to use Scala's XML processing to
 just get at the children:

 bind (item, (xhtml \\ items).first.child, ...)

 Kind of ugly. I still can't find the example that David posted but it seemed
 a lot cleaner.

 Derek

 On Wed, Sep 10, 2008 at 12:39 PM, Kris Nuttycombe
 [EMAIL PROTECTED] wrote:

 Hrm. I think that I need to do something extra there to extract and
 bind against just the order:items element to avoid re-binding over
 the entire contents of the snippet.

 Marius, can you expand at all on using snippet attributes for case
 (1)? I've googled around and looked at all of the template docs I can
 find and am not really following how to take that approach.

 Thanks,

 Kris

 On Wed, Sep 10, 2008 at 12:08 PM, Derek Chen-Becker
 [EMAIL PROTECTED] wrote:
  I think the bind would look something like this (assuming that xhtml is
  the
  input NodeSeq):
 
  bind(order, xhtml, id -- Text(your_id_here),
   items -- your_items.flatMap{ item =
  bind(item,
  xhtml, name -- Text(item.name), cost -- Text(item.cost)) })
 
  I seem to remember David giving an example of a nested bind but I can't
  find
  it.
 
  Derek
 
  On Wed, Sep 10, 2008 at 11:37 AM, Marius [EMAIL PROTECTED]
  wrote:
 
  Hi,
 
  1. You can use snippet attributes.
  2. You can leave the divs in the template page and attach only
  certain attributes from the snippet. Note that Scala XML API is
  immutable but that was never an inconvenience for me :) ... you could
  pattern match them easily.
 
  Br's,
  Marius
 
  On Sep 10, 8:05 pm, Kris Nuttycombe [EMAIL PROTECTED]
  wrote:
   Hi, all,
  
   I'm in the process of moving a Rails app over to Lift, and have a
   couple of questions about how to achieve a few things that aren't
   really addressed in the basic template tutorials.
  
   First, I have a situation where I have a list of orders, each of
   which
   has some number of items. What would the binding look like for
   something like the following?
  
   lift:snippet type=Orders:list
 order:idsample_order_id/order:id
 order:items
   item:nameSample Item/item:name
   item:cost$0.00/item:cost
 /order:items
   /lift:snippet
  
   Secondly, I know that there have been some additions since the
   discussion on dynamic node attributes
  
   here:http://groups.google.com/group/liftweb/browse_thread/thread/c7fe7b4b3...
  
   What is the best way to go about porting something that looks like
   this in Rails:
  
   div style=color:blue;cursor:pointer
   onclick=document.getElementById('order_%=
   order.id%').style.display='block';this.style.display='none'[View
   Details]/div
  
   div id=order_%= order.id % style=display:none
...
   /div
  
   It seems a bit odd to use different snippet functions to write the
   onclick and id attributes. I know that I could move the generation of
   both divs into the snippet, but that won't make our designers happy
   because they won't be able to play with the functionality in their
   browsers.
  
   Thanks,
  
   Kris
 
 
 
  
 




 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: One further: JPA + JTA + Lift

2008-09-10 Thread Kris Nuttycombe

Thanks a lot, Martin. That's definitely useful to know, and, wow...
too much magic.

On Wed, Sep 10, 2008 at 2:23 PM, Martin Ellis [EMAIL PROTECTED] wrote:

 On Wed, Sep 10, 2008 at 4:27 PM, Kris Nuttycombe
 [EMAIL PROTECTED] wrote:
 The only question I have is thread safety - it doesn't seem
 like I should really be using a variable on the singleton to store the
 transaction; should I instead be creating a separate RequestVar to
 hold it?

 It is thread safe to use a singleton - in fact, it's what Sun do in
 the code that accompanies the Java EE Tutorial...

 web/books/src/main/java/com/sun/books/listeners/ContextListener.java:

 public final class ContextListener implements ServletContextListener {
@PersistenceUnit
private EntityManagerFactory emf;
private ServletContext context = null;
@Resource
private UserTransaction utx;

public void contextInitialized(ServletContextEvent event) {
context = event.getServletContext();

try {
context.setAttribute(emf, emf);
Globals.UTX = utx;


 ... where Globals is defined as:

 public class Globals {
public static UserTransaction UTX;
 }


 Hence, using val instead of def should be fine.

 The begin() and commit() javadoc on UserTransaction:
 Create a new transaction and associate it with the current thread.
 Complete the transaction associated with the current thread. When
 this method completes, the thread is no longer associated with a
 transaction.

 The transaction is associated with the thread that called begin()
 'internally', so there's no need to associate it with a thread
 manually.

 See also:
 http://java.sun.com/javaee/5/docs/tutorial/doc/bnafo.html

 Martin

 


--~--~-~--~~~---~--~~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/liftweb?hl=en
-~--~~~~--~~--~--~---



[Lift] Re: Template questions

2008-09-10 Thread Marius

Kris,

Having a template like (slightly changed from your example so the
values to be dynamic):

lift:Hello.orderList
order:id/
order:items
item:name/
item:cost/
/order:items
/lift:Hello.orderList


and the Scala code:

  case class OrderItem(name:String, cost:String)

  def orderList(xhtml: Group): NodeSeq = {

val orderList = OrderItem(first, 9.99$) :: OrderItem(second,
19.99$) :: Nil

val content = (xhtml \\ items).first.descendant

println(Content  + content)

bind(order, xhtml,
 id - Text(My order Id),
 items - Group(orderList flatMap (elem = bind(item,
content, name - Text(elem.name), cost - Text(elem.cost
)

  }
should work just fine (at least for me it does).

 regarding your compile error the flatMap call returns an
Iterable[scala.xml.Node] which does not conform with NodeSeq return
Type. To fix this you can probably wrap everything into a Group like:

private def bindItems(xhtml : NodeSeq,
items :java.util.Collection[Item]) : NodeSeq = {
Group(items.flatMap(item =
  bind(item, xhtml,
   name -- Text(item.getName
  }

... just out of curiosity is there a reason why you;re using
java,util.collection and not Scala List, Seq etc?


Br's,
Marius

On Sep 11, 12:16 am, Kris Nuttycombe [EMAIL PROTECTED]
wrote:
 Man, I really wish I understood the Scala type system better.

   def list(xhtml : NodeSeq) : NodeSeq = {
 val orders = EM.createQuery[Order](FROM Order).getResultList
 orders.flatMap(order =
   bind(order, xhtml,
id -- Text(order.getId.toString),
uuid -- Text(order.getUuid.toString),
items -- bindItems((xhtml \\ items).first.child,
 order.getItems))
 )
   }

   private def bindItems(xhtml : NodeSeq, items :
 java.util.Collection[Item]) : NodeSeq = {
 items.flatMap(item =
   bind(item, xhtml,
name -- Text(item.getName)))
   }

 [WARNING] 
 /home/knuttycombe/work/gcsi/gcsi-admin/src/main/scala/com/gaiam/gcsi/snippet/Orders.scala:33:
 error: type mismatch;
 [WARNING]  found   : Iterable[scala.xml.Node]
 [WARNING]  required: scala.xml.NodeSeq
 [WARNING] items.flatMap(item =
 [WARNING]  ^
 [WARNING] one error found

 That's the only error, too; the list function compiles just fine.
 I've tried making that items.flatMap[NodeSeq], adding an explicit cast
 .asInstanceOf[NodeSeq] to the results of the binding, and split
 bindItems out into a separate function just to try to make things look
 as much the same as possible. WTF?

 Kris

 On Wed, Sep 10, 2008 at 2:28 PM, Derek Chen-Becker

 [EMAIL PROTECTED] wrote:
  Sorry, forgot about that. You might be able to use Scala's XML processing to
  just get at the children:

  bind (item, (xhtml \\ items).first.child, ...)

  Kind of ugly. I still can't find the example that David posted but it seemed
  a lot cleaner.

  Derek

  On Wed, Sep 10, 2008 at 12:39 PM, Kris Nuttycombe
  [EMAIL PROTECTED] wrote:

  Hrm. I think that I need to do something extra there to extract and
  bind against just the order:items element to avoid re-binding over
  the entire contents of the snippet.

  Marius, can you expand at all on using snippet attributes for case
  (1)? I've googled around and looked at all of the template docs I can
  find and am not really following how to take that approach.

  Thanks,

  Kris

  On Wed, Sep 10, 2008 at 12:08 PM, Derek Chen-Becker
  [EMAIL PROTECTED] wrote:
   I think the bind would look something like this (assuming that xhtml is
   the
   input NodeSeq):

   bind(order, xhtml, id -- Text(your_id_here),
items -- your_items.flatMap{ item =
   bind(item,
   xhtml, name -- Text(item.name), cost -- Text(item.cost)) })

   I seem to remember David giving an example of a nested bind but I can't
   find
   it.

   Derek

   On Wed, Sep 10, 2008 at 11:37 AM, Marius [EMAIL PROTECTED]
   wrote:

   Hi,

   1. You can use snippet attributes.
   2. You can leave the divs in the template page and attach only
   certain attributes from the snippet. Note that Scala XML API is
   immutable but that was never an inconvenience for me :) ... you could
   pattern match them easily.

   Br's,
   Marius

   On Sep 10, 8:05 pm, Kris Nuttycombe [EMAIL PROTECTED]
   wrote:
Hi, all,

I'm in the process of moving a Rails app over to Lift, and have a
couple of questions about how to achieve a few things that aren't
really addressed in the basic template tutorials.

First, I have a situation where I have a list of orders, each of
which
has some number of items. What would the binding look like for
something like the following?

lift:snippet type=Orders:list
  order:idsample_order_id/order:id
  order:items
item:nameSample Item/item:name
item:cost$0.00/item:cost
  /order:items
/lift:snippet

Secondly, I know that there 

[Lift] Re: Template questions

2008-09-10 Thread Jorge Ortiz

Group won't work, as it too needs a Seq[Node], an Iterable[Node] just won't do.

Kris, this problem is certainly annoying and stems from the type
differences between Java collections and Scala collections. You need
your items argument to either be a proper Scala collection (Seq or
any of it's subclasses (List, Array, etc)) or you can wrap your Java
collections with the wrappers in scala.collections.jcl (the
Conversions object has some convenient implicit conversions). These
wrappers all extend Scala's Seq, which is what you want.

--j

On Wed, Sep 10, 2008 at 2:51 PM, Marius [EMAIL PROTECTED] wrote:

 Kris,

 Having a template like (slightly changed from your example so the
 values to be dynamic):

lift:Hello.orderList
order:id/
order:items
item:name/
item:cost/
/order:items
/lift:Hello.orderList


 and the Scala code:

  case class OrderItem(name:String, cost:String)

  def orderList(xhtml: Group): NodeSeq = {

val orderList = OrderItem(first, 9.99$) :: OrderItem(second,
 19.99$) :: Nil

val content = (xhtml \\ items).first.descendant

println(Content  + content)

bind(order, xhtml,
 id - Text(My order Id),
 items - Group(orderList flatMap (elem = bind(item,
 content, name - Text(elem.name), cost - Text(elem.cost
)

  }
 should work just fine (at least for me it does).

  regarding your compile error the flatMap call returns an
 Iterable[scala.xml.Node] which does not conform with NodeSeq return
 Type. To fix this you can probably wrap everything into a Group like:

 private def bindItems(xhtml : NodeSeq,
 items :java.util.Collection[Item]) : NodeSeq = {
Group(items.flatMap(item =
  bind(item, xhtml,
   name -- Text(item.getName
  }

 ... just out of curiosity is there a reason why you;re using
 java,util.collection and not Scala List, Seq etc?


 Br's,
 Marius

 On Sep 11, 12:16 am, Kris Nuttycombe [EMAIL PROTECTED]
 wrote:
 Man, I really wish I understood the Scala type system better.

   def list(xhtml : NodeSeq) : NodeSeq = {
 val orders = EM.createQuery[Order](FROM Order).getResultList
 orders.flatMap(order =
   bind(order, xhtml,
id -- Text(order.getId.toString),
uuid -- Text(order.getUuid.toString),
items -- bindItems((xhtml \\ items).first.child,
 order.getItems))
 )
   }

   private def bindItems(xhtml : NodeSeq, items :
 java.util.Collection[Item]) : NodeSeq = {
 items.flatMap(item =
   bind(item, xhtml,
name -- Text(item.getName)))
   }

 [WARNING] 
 /home/knuttycombe/work/gcsi/gcsi-admin/src/main/scala/com/gaiam/gcsi/snippet/Orders.scala:33:
 error: type mismatch;
 [WARNING]  found   : Iterable[scala.xml.Node]
 [WARNING]  required: scala.xml.NodeSeq
 [WARNING] items.flatMap(item =
 [WARNING]  ^
 [WARNING] one error found

 That's the only error, too; the list function compiles just fine.
 I've tried making that items.flatMap[NodeSeq], adding an explicit cast
 .asInstanceOf[NodeSeq] to the results of the binding, and split
 bindItems out into a separate function just to try to make things look
 as much the same as possible. WTF?

 Kris

 On Wed, Sep 10, 2008 at 2:28 PM, Derek Chen-Becker

 [EMAIL PROTECTED] wrote:
  Sorry, forgot about that. You might be able to use Scala's XML processing 
  to
  just get at the children:

  bind (item, (xhtml \\ items).first.child, ...)

  Kind of ugly. I still can't find the example that David posted but it 
  seemed
  a lot cleaner.

  Derek

  On Wed, Sep 10, 2008 at 12:39 PM, Kris Nuttycombe
  [EMAIL PROTECTED] wrote:

  Hrm. I think that I need to do something extra there to extract and
  bind against just the order:items element to avoid re-binding over
  the entire contents of the snippet.

  Marius, can you expand at all on using snippet attributes for case
  (1)? I've googled around and looked at all of the template docs I can
  find and am not really following how to take that approach.

  Thanks,

  Kris

  On Wed, Sep 10, 2008 at 12:08 PM, Derek Chen-Becker
  [EMAIL PROTECTED] wrote:
   I think the bind would look something like this (assuming that xhtml is
   the
   input NodeSeq):

   bind(order, xhtml, id -- Text(your_id_here),
items -- your_items.flatMap{ item =
   bind(item,
   xhtml, name -- Text(item.name), cost -- Text(item.cost)) })

   I seem to remember David giving an example of a nested bind but I can't
   find
   it.

   Derek

   On Wed, Sep 10, 2008 at 11:37 AM, Marius [EMAIL PROTECTED]
   wrote:

   Hi,

   1. You can use snippet attributes.
   2. You can leave the divs in the template page and attach only
   certain attributes from the snippet. Note that Scala XML API is
   immutable but that was never an inconvenience for me :) ... you could
   pattern match them easily.

   Br's,
   Marius

   On Sep 10, 8:05 pm, Kris Nuttycombe [EMAIL PROTECTED]
  

[Lift] Re: Template questions

2008-09-10 Thread Kris Nuttycombe

It's ugly, but this works:

(new java.util.ArrayList[Subscription](items)).flatMap(...)

I guess that Scala is uncomfortable imposing order on something that's
not explicitly ordered?

Kris

On Wed, Sep 10, 2008 at 4:23 PM, Kris Nuttycombe
[EMAIL PROTECTED] wrote:
 I quickly found out that Group didn't work, but I'm still stymied; why
 does Conversions provide converters for Set, List, and Map, but not
 your basic everyday java.util.Collection? My existing code was using
 an implicit conversion of my own creation:

  implicit def collToWrapper[A](coll : java.util.Collection[A]) = new
 CollectionWrapper[A] {override def underlying = coll}

 but that doesn't solve the problem. The reason that I'm using the
 java.util collections is because all of my model classes are EJB3
 entities, with most of the associations between models wired as
 java.util.Collection.

 Thanks,

 Kris

 On Wed, Sep 10, 2008 at 4:11 PM, Jorge Ortiz [EMAIL PROTECTED] wrote:

 Group won't work, as it too needs a Seq[Node], an Iterable[Node] just won't 
 do.

 Kris, this problem is certainly annoying and stems from the type
 differences between Java collections and Scala collections. You need
 your items argument to either be a proper Scala collection (Seq or
 any of it's subclasses (List, Array, etc)) or you can wrap your Java
 collections with the wrappers in scala.collections.jcl (the
 Conversions object has some convenient implicit conversions). These
 wrappers all extend Scala's Seq, which is what you want.

 --j

 On Wed, Sep 10, 2008 at 2:51 PM, Marius [EMAIL PROTECTED] wrote:

 Kris,

 Having a template like (slightly changed from your example so the
 values to be dynamic):

lift:Hello.orderList
order:id/
order:items
item:name/
item:cost/
/order:items
/lift:Hello.orderList


 and the Scala code:

  case class OrderItem(name:String, cost:String)

  def orderList(xhtml: Group): NodeSeq = {

val orderList = OrderItem(first, 9.99$) :: OrderItem(second,
 19.99$) :: Nil

val content = (xhtml \\ items).first.descendant

println(Content  + content)

bind(order, xhtml,
 id - Text(My order Id),
 items - Group(orderList flatMap (elem = bind(item,
 content, name - Text(elem.name), cost - Text(elem.cost
)

  }
 should work just fine (at least for me it does).

  regarding your compile error the flatMap call returns an
 Iterable[scala.xml.Node] which does not conform with NodeSeq return
 Type. To fix this you can probably wrap everything into a Group like:

 private def bindItems(xhtml : NodeSeq,
 items :java.util.Collection[Item]) : NodeSeq = {
Group(items.flatMap(item =
  bind(item, xhtml,
   name -- Text(item.getName
  }

 ... just out of curiosity is there a reason why you;re using
 java,util.collection and not Scala List, Seq etc?


 Br's,
 Marius

 On Sep 11, 12:16 am, Kris Nuttycombe [EMAIL PROTECTED]
 wrote:
 Man, I really wish I understood the Scala type system better.

   def list(xhtml : NodeSeq) : NodeSeq = {
 val orders = EM.createQuery[Order](FROM Order).getResultList
 orders.flatMap(order =
   bind(order, xhtml,
id -- Text(order.getId.toString),
uuid -- Text(order.getUuid.toString),
items -- bindItems((xhtml \\ items).first.child,
 order.getItems))
 )
   }

   private def bindItems(xhtml : NodeSeq, items :
 java.util.Collection[Item]) : NodeSeq = {
 items.flatMap(item =
   bind(item, xhtml,
name -- Text(item.getName)))
   }

 [WARNING] 
 /home/knuttycombe/work/gcsi/gcsi-admin/src/main/scala/com/gaiam/gcsi/snippet/Orders.scala:33:
 error: type mismatch;
 [WARNING]  found   : Iterable[scala.xml.Node]
 [WARNING]  required: scala.xml.NodeSeq
 [WARNING] items.flatMap(item =
 [WARNING]  ^
 [WARNING] one error found

 That's the only error, too; the list function compiles just fine.
 I've tried making that items.flatMap[NodeSeq], adding an explicit cast
 .asInstanceOf[NodeSeq] to the results of the binding, and split
 bindItems out into a separate function just to try to make things look
 as much the same as possible. WTF?

 Kris

 On Wed, Sep 10, 2008 at 2:28 PM, Derek Chen-Becker

 [EMAIL PROTECTED] wrote:
  Sorry, forgot about that. You might be able to use Scala's XML 
  processing to
  just get at the children:

  bind (item, (xhtml \\ items).first.child, ...)

  Kind of ugly. I still can't find the example that David posted but it 
  seemed
  a lot cleaner.

  Derek

  On Wed, Sep 10, 2008 at 12:39 PM, Kris Nuttycombe
  [EMAIL PROTECTED] wrote:

  Hrm. I think that I need to do something extra there to extract and
  bind against just the order:items element to avoid re-binding over
  the entire contents of the snippet.

  Marius, can you expand at all on using snippet attributes for case
  (1)? I've googled around and looked at all of the template docs I can
  find and am