[Lift] Re: One further: JPA + JTA + Lift
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
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)
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)
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
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
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
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
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
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
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
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