You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/04/09 20:29:11 UTC

svn commit: r646473 - in /tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry: hibernate/HibernateModule.java internal/hibernate/HibernateEntityValueEncoder.java

Author: hlship
Date: Wed Apr  9 11:29:10 2008
New Revision: 646473

URL: http://svn.apache.org/viewvc?rev=646473&view=rev
Log:
TAPESTRY-2239: The automatic ValueEncoder for Hibernate entities will sometimes encode an entity as null (rather than its primary key)

Modified:
    tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/hibernate/HibernateModule.java
    tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java

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=646473&r1=646472&r2=646473&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 Wed Apr  9 11:29:10 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 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.
@@ -16,27 +16,17 @@
 
 import org.apache.tapestry.ValueEncoder;
 import org.apache.tapestry.internal.InternalConstants;
-import org.apache.tapestry.internal.hibernate.DefaultHibernateConfigurer;
-import org.apache.tapestry.internal.hibernate.EntityPersistentFieldStrategy;
-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.internal.hibernate.*;
 import org.apache.tapestry.ioc.Configuration;
+import static org.apache.tapestry.ioc.IOCConstants.PERTHREAD_SCOPE;
 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;
 import org.apache.tapestry.ioc.annotations.InjectService;
 import org.apache.tapestry.ioc.annotations.Scope;
 import org.apache.tapestry.ioc.annotations.Symbol;
-import org.apache.tapestry.ioc.services.ClassNameLocator;
-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.ioc.services.*;
 import org.apache.tapestry.services.AliasContribution;
 import org.apache.tapestry.services.PersistentFieldStrategy;
 import org.apache.tapestry.services.ValueEncoderFactory;
@@ -141,38 +131,45 @@
     }
 
     /**
-     * Contributes {@link 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.
+     * Contributes {@link 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)
+                                                    final TypeCoercer typeCoercer,
+                                                    final PropertyAccess propertyAccess)
     {
-    	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);
-    	}
-    }
-    
+        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, propertyAccess,
+                                                           typeCoercer);
+                }
+            };
+
+            configuration.add(entityClass, factory);
+        }
+    }
+
     /**
-     * Contributes the following: <dl> <dt>entity</dt> <dd>Stores the id of the entity and reloads from the {@link Session}</dd> </dl>
+     * Contributes the following: <dl> <dt>entity</dt> <dd>Stores the id of the entity and reloads from the {@link
+     * Session}</dd> </dl>
      */
-    public void contributePersistentFieldManager(MappedConfiguration<String, PersistentFieldStrategy> configuration, ObjectLocator locator)
+    public void contributePersistentFieldManager(MappedConfiguration<String, PersistentFieldStrategy> configuration,
+                                                 ObjectLocator locator)
     {
-    	configuration.add("entity", locator.autobuild(EntityPersistentFieldStrategy.class));
+        configuration.add("entity", locator.autobuild(EntityPersistentFieldStrategy.class));
     }
-    
+
 }

Modified: 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=646473&r1=646472&r2=646473&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java (original)
+++ tapestry/tapestry5/trunk/tapestry-hibernate/src/main/java/org/apache/tapestry/internal/hibernate/HibernateEntityValueEncoder.java Wed Apr  9 11:29:10 2008
@@ -17,51 +17,61 @@
 import org.apache.tapestry.ValueEncoder;
 import org.apache.tapestry.ioc.internal.util.Defense;
 import org.apache.tapestry.ioc.internal.util.InternalUtils;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.ioc.services.PropertyAdapter;
 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;
 
 import java.io.Serializable;
 
-public final class HibernateEntityValueEncoder<E> implements ValueEncoder<E> {
+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;
+    private final String _idPropertyName;
+    private final PropertyAdapter _propertyAdapter;
 
-    public HibernateEntityValueEncoder(Class<E> entityClass, PersistentClass persistentClass, Session session, TypeCoercer typeCoercer) {
-        super();
+    public HibernateEntityValueEncoder(Class<E> entityClass, PersistentClass persistentClass, Session session,
+                                       PropertyAccess propertyAccess, TypeCoercer typeCoercer)
+    {
         _entityClass = entityClass;
-        _persistentClass = persistentClass;
         _session = session;
         _typeCoercer = typeCoercer;
 
-        Property property = _persistentClass.getIdentifierProperty();
-        _idGetter = property.getPropertyAccessor(_entityClass).getGetter(_entityClass, property.getName());
+        Property property = persistentClass.getIdentifierProperty();
+
+        _idPropertyName = property.getName();
+
+        _propertyAdapter = propertyAccess.getAdapter(_entityClass).getPropertyAdapter(_idPropertyName);
     }
 
-    public String toClient(E value) {
 
+    public String toClient(E value)
+    {
         if (value == null) return null;
 
-        Object id = _idGetter.get(value);
+        Object id = _propertyAdapter.get(value);
+
+        if (id == null)
+            throw new IllegalStateException(String.format(
+                    "Entity %s has an %s property of null; this probably means that it has not been persisted yet.",
+                    value, _idPropertyName));
 
         return _typeCoercer.coerce(id, String.class);
     }
 
     @SuppressWarnings("unchecked")
-    public E toValue(String clientValue) {
-
+    public E toValue(String clientValue)
+    {
         if (InternalUtils.isBlank(clientValue)) return null;
 
+        Object id = _typeCoercer.coerce(clientValue, _propertyAdapter.getType());
 
-        Class<?> idType = _idGetter.getReturnType();
-
-        Object id = _typeCoercer.coerce(clientValue, idType);
         Serializable ser = Defense.cast(id, Serializable.class, "id");
+
         return (E) _session.get(_entityClass, ser);
     }