Feels good to do some commits. I'm almost done with the @Once annotation.

I encountered an interesting situation when doing this; handling composite id's. But the type coercion was the perfect solution to it. If you have an entity with a composite id (some other custom object) just add a coercion for it and it will get handled perfectly. But I'm not terribly concerned about supporting composite id's anyway since it doesn't seem like a major use case.

Howard Lewis Ship wrote:
Looks awesome!

On Sat, Mar 8, 2008 at 7:23 AM,  <[EMAIL PROTECTED]> wrote:
Author: dadams
 Date: Sat Mar  8 07:23:21 2008
 New Revision: 634989

 URL: http://svn.apache.org/viewvc?rev=634989&view=rev
 Log:
 TAPESTRY-1653: Provide automatic ValueEncoders for Hibernate entities

 Added:
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
    tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml
 Modified:
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
    tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
    
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
    tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml

 Modified: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
 (original)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
 Sat Mar  8 07:23:21 2008
 @@ -14,12 +14,17 @@

  package org.apache.tapestry.hibernate;

 +import org.apache.tapestry.ValueEncoder;
  import org.apache.tapestry.internal.InternalConstants;
  import org.apache.tapestry.internal.hibernate.DefaultHibernateConfigurer;
 +import org.apache.tapestry.internal.hibernate.HibernateEntityValueEncoder;
  import org.apache.tapestry.internal.hibernate.HibernateSessionManagerImpl;
  import org.apache.tapestry.internal.hibernate.HibernateSessionSourceImpl;
  import org.apache.tapestry.internal.hibernate.PackageNameHibernateConfigurer;
  import org.apache.tapestry.ioc.Configuration;
 +import org.apache.tapestry.ioc.MappedConfiguration;
 +import org.apache.tapestry.ioc.ObjectLocator;
 +
  import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
  import org.apache.tapestry.ioc.OrderedConfiguration;
  import org.apache.tapestry.ioc.annotations.Inject;
 @@ -30,11 +35,15 @@
  import org.apache.tapestry.ioc.services.PerthreadManager;
  import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
  import org.apache.tapestry.ioc.services.RegistryShutdownHub;
 +import org.apache.tapestry.ioc.services.TypeCoercer;
  import org.apache.tapestry.services.AliasContribution;
 +import org.apache.tapestry.services.ValueEncoderFactory;
  import org.hibernate.Session;
 +import org.hibernate.mapping.PersistentClass;
  import org.slf4j.Logger;

  import java.util.Collection;
 +import java.util.Iterator;
  import java.util.List;

  public class HibernateModule
 @@ -129,4 +138,30 @@
         config.add("PackageName", new 
PackageNameHibernateConfigurer(packageManager, classNameLocator));
     }

 +    /**
 +     * Contributes [EMAIL PROTECTED] ValueEncoderFactory}s for all registered 
Hibernate entity classes. Encoding and decoding are based
 +     * on the id property value of the entity using type coercion. Hence, if 
the id can be coerced to a String and back then
 +     * the entity can be coerced.
 +     */
 +    @SuppressWarnings("unchecked")
 +    public static void contributeValueEncoderSource(MappedConfiguration<Class, 
ValueEncoderFactory> configuration,
 +                                                    final 
HibernateSessionSource sessionSource,
 +                                                    final Session session,
 +                                                    final TypeCoercer 
typeCoercer)
 +    {
 +       org.hibernate.cfg.Configuration config = 
sessionSource.getConfiguration();
 +       Iterator<PersistentClass> mappings = config.getClassMappings();
 +       while(mappings.hasNext()) {
 +               final PersistentClass persistentClass = mappings.next();
 +               final Class entityClass = persistentClass.getMappedClass();
 +
 +                       ValueEncoderFactory factory = new 
ValueEncoderFactory() {
 +                               public ValueEncoder create(Class type) {
 +                                       return new 
HibernateEntityValueEncoder(entityClass, persistentClass, session, typeCoercer);
 +                               }
 +                       };
 +
 +                       configuration.add(entityClass, factory);
 +       }
 +    }
  }

 Added: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java?rev=634989&view=auto
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
 (added)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java
 Sat Mar  8 07:23:21 2008
 @@ -0,0 +1,59 @@
 +// Copyright 2008 The Apache Software Foundation
 +//
 +// Licensed under the Apache License, Version 2.0 (the "License");
 +// you may not use this file except in compliance with the License.
 +// You may obtain a copy of the License at
 +//
 +//     http://www.apache.org/licenses/LICENSE-2.0
 +//
 +// Unless required by applicable law or agreed to in writing, software
 +// distributed under the License is distributed on an "AS IS" BASIS,
 +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 +// See the License for the specific language governing permissions and
 +// limitations under the License.
 +
 +package org.apache.tapestry.internal.hibernate;
 +
 +import java.io.Serializable;
 +
 +import org.apache.tapestry.ValueEncoder;
 +import org.apache.tapestry.ioc.internal.util.Defense;
 +import org.apache.tapestry.ioc.services.TypeCoercer;
 +import org.hibernate.Session;
 +import org.hibernate.mapping.PersistentClass;
 +import org.hibernate.mapping.Property;
 +import org.hibernate.property.Getter;
 +
 +public final class HibernateEntityValueEncoder<E> implements ValueEncoder<E> {
 +       private final Class<E> _entityClass;
 +       private final PersistentClass _persistentClass;
 +       private final Session _session;
 +       private final TypeCoercer _typeCoercer;
 +       private final Getter _idGetter;
 +
 +       public HibernateEntityValueEncoder(Class<E> entityClass, 
PersistentClass persistentClass, Session session, TypeCoercer typeCoercer) {
 +               super();
 +               _entityClass = entityClass;
 +               _persistentClass = persistentClass;
 +               _session = session;
 +               _typeCoercer = typeCoercer;
 +
 +               Property property = _persistentClass.getIdentifierProperty();
 +               _idGetter = 
property.getPropertyAccessor(_entityClass).getGetter(_entityClass, 
property.getName());
 +       }
 +
 +       public String toClient(E value) {
 +               Object id = _idGetter.get(value);
 +               return _typeCoercer.coerce(id, String.class);
 +       }
 +
 +       @SuppressWarnings("unchecked")
 +       public E toValue(String clientValue) {
 +               Class<?> idType = _idGetter.getReturnType();
 +
 +               Object id = _typeCoercer.coerce(clientValue, idType);
 +               Serializable ser = Defense.cast(id, Serializable.class, "id");
 +               return (E)_session.get(_entityClass, ser);
 +       }
 +
 +}

 Added: tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt?rev=634989&view=auto
 ==============================================================================
 --- tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt 
(added)
 +++ tapestry/tapestry5/trunk/tapestry-hibernate/src/site/apt/userguide.apt Sat 
Mar  8 07:23:21 2008
 @@ -0,0 +1,31 @@
 +  ----
 +  User Guide
 +  ----
 +
 +Entity value encoding
 +
 +  Value encoders are automatically created for all mapped Hibernate entity 
types. This is done by encoding the entity as it's
 +  id (coerced to a String) and decoding the entity by looking it up in the 
Hibernate Session using the encoded id. Consider
 +  the following:
 +
 ++----+
 +public class ViewPerson {
 +  @Property
 +  private Person _person;
 +
 +  void onActivate(Person person)
 +  {
 +    _person = person;
 +  }
 +}
 ++----+
 +
 ++----+
 +<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
 +<body>
 +  The person's name is: ${person.name}
 +</body>
 +</html>
 ++----+
 +
 +  Accessing the page as <</viewperson/152>> would load the Person entity with 
id 152 and use that as the page context.

 Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml (original)
 +++ tapestry/tapestry5/trunk/tapestry-hibernate/src/site/site.xml Sat Mar  8 
07:23:21 2008
 @@ -40,6 +40,7 @@
     <menu name="Quick Links">
       <item name="About" href="index.html"/>
       <item name="Configuration" href="conf.html"/>
 +      <item name="User guide" href="userguide.html" />
       <item name="Download" href="http://tapestry.apache.org/download.html"/>
     </menu>


 Modified: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
 (original)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/apache/tapestry/hibernate/integration/TapestryHibernateIntegrationTests.java
 Sat Mar  8 07:23:21 2008
 @@ -25,12 +25,18 @@
         super("src/test/webapp");
     }

 -    /** Only needed until actual integration tests are put in. Just proves 
the integration
 -     * tests are set up correctly.
 -     */
 -    public void test_placeholder() throws Exception {
 -               open("/");
 -               // just make sure we can get the hibernate Session
 -               assertTrue(getText("//[EMAIL PROTECTED]'session']").length() > 
0);
 +       public void test_valueencode_all_entity_types() throws Exception {
 +               open("/encodeentities");
 +
 +               assertEquals(0, getText("//[EMAIL 
PROTECTED]'name']").length());
 +
 +               // need to create an entity in order to link with one
 +               clickAndWait("//[EMAIL PROTECTED]'createentity']");
 +               assertEquals("name", getText("//[EMAIL PROTECTED]'name']"));
 +
 +               // should return null for missing objects
 +               open("/encodeentities/9999");
 +               assertEquals(0, getText("//[EMAIL 
PROTECTED]'name']").length());
        }
 +
  }

 Modified: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
 (original)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/entities/User.java
 Sat Mar  8 07:23:21 2008
 @@ -22,67 +22,68 @@
  @Entity
  public class User
  {
 +       // NOTE: Hibernate doesn't understand the '_' syntax. It will end up 
putting underscores on all the properties
     @Id @GeneratedValue
 -    private Long _id;
 +    private Long id;

 -    private String _firstName;
 +    private String firstName;

 -    private String _lastName;
 +    private String lastName;

 -    private String _email;
 +    private String email;

 -    private String _encodedPassword;
 +    private String encodedPassword;

     @Version
 -    private int _version;
 +    private int version;

     public String getEmail()
     {
 -        return _email;
 +        return email;
     }

     public String getEncodedPassword()
     {
 -        return _encodedPassword;
 +        return encodedPassword;
     }

     public String getFirstName()
     {
 -        return _firstName;
 +        return firstName;
     }

     public Long getId()
     {
 -        return _id;
 +        return id;
     }

     public String getLastName()
     {
 -        return _lastName;
 +        return lastName;
     }

     public int getVersion()
     {
 -        return _version;
 +        return version;
     }

     public void setEmail(String email)
     {
 -        _email = email;
 +        this.email = email;
     }

     public void setEncodedPassword(String encodedPassword)
     {
 -        _encodedPassword = encodedPassword;
 +        this.encodedPassword = encodedPassword;
     }

     public void setFirstName(String firstName)
     {
 -        _firstName = firstName;
 +        this.firstName = firstName;
     }

     public void setLastName(String lastName)
     {
 -        _lastName = lastName;
 +        this.lastName = lastName;
     }
  }

 Added: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java?rev=634989&view=auto
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
 (added)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/EncodeEntities.java
 Sat Mar  8 07:23:21 2008
 @@ -0,0 +1,37 @@
 +package org.example.app0.pages;
 +
 +import java.util.List;
 +
 +import org.apache.tapestry.annotations.Property;
 +import org.apache.tapestry.ioc.annotations.Inject;
 +import org.example.app0.entities.User;
 +import org.hibernate.Session;
 +
 +public class EncodeEntities {
 +       @Inject
 +       @Property
 +       private Session _session;
 +
 +       @SuppressWarnings("unused")
 +       @Property
 +       private User _user;
 +
 +       void onCreate() {
 +               User user = new User();
 +               user.setFirstName("name");
 +               _session.save(user);
 +       }
 +
 +       @SuppressWarnings("unchecked")
 +       User onPassivate() {
 +               List<User> users = _session.createQuery("from User").list();
 +               if (users.isEmpty())
 +                       return null;
 +
 +               return users.get(0);
 +       }
 +
 +       void onActivate(User user) {
 +               _user = user;
 +       }
 +}

 Modified: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
 (original)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/java/org/example/app0/pages/Start.java
 Sat Mar  8 07:23:21 2008
 @@ -14,13 +14,6 @@

  package org.example.app0.pages;

 -import org.apache.tapestry.annotations.Property;
 -import org.apache.tapestry.ioc.annotations.Inject;
 -import org.hibernate.Session;
 -
  public class Start {
 -       @Property
 -       @Inject
 -       private Session _session;

  }

 Modified: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
 (original)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/resources/hibernate.cfg.xml
 Sat Mar  8 07:23:21 2008
 @@ -23,20 +23,19 @@

   <session-factory>
     <property 
name="hibernate.connection.driver_class">org.hsqldb.jdbcDriver</property>
 -    <property 
name="hibernate.connection.url">jdbc:hsqldb:file:target/unit-testdb</property>
 +    <property name="hibernate.connection.url">jdbc:hsqldb:mem:test</property>
     <property name="hibernate.connection.username">sa</property>
     <property 
name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>

     <property name="show_sql">true</property>
     <property name="format_sql">true</property>
 -    <property name="hbm2ddl.auto">create-drop</property>
 -
 +    <property name="hbm2ddl.auto">update</property>
 +
     <property name="hibernate.c3p0.min_size">5</property>
     <property name="hibernate.c3p0.max_size">20</property>
     <property name="hibernate.c3p0.timeout">300</property>
     <property name="hibernate.c3p0.max_statements">50</property>
     <property name="hibernate.c3p0.idle_test_period">3000</property>
 -
   </session-factory>



 Added: 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml?rev=634989&view=auto
 ==============================================================================
 --- 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml 
(added)
 +++ 
tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/EncodeEntities.tml 
Sat Mar  8 07:23:21 2008
 @@ -0,0 +1,6 @@
 +<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd";>
 +<body>
 +       <p>entity name: <span id="name"><t:if 
test="user">${user.firstName}</t:if></span></p>
 +       <p>create entity: <t:eventlink event="create" t:id="createentity">create an 
entity</t:eventlink></p>
 +</body>
 +</html>
 \ No newline at end of file

 Modified: tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml
 URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml?rev=634989&r1=634988&r2=634989&view=diff
 ==============================================================================
 --- tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml 
(original)
 +++ tapestry/tapestry5/trunk/tapestry-hibernate/src/test/webapp/Start.tml Sat 
Mar  8 07:23:21 2008
 @@ -4,6 +4,5 @@
   </head>
   <body>
     <h2>Test application for tapestry-hibernate integration tests</h2>
 -    The Hibernate session: <span id="session">${session}</span>
   </body>
  </html>








---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to