Hibernate SVN: r15268 - in core/trunk/core/src/main: java/org/hibernate/hql/ast/exec and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-08 00:13:07 -0400 (Wed, 08 Oct 2008)
New Revision: 15268
Modified:
core/trunk/core/src/main/antlr/sql-gen.g
core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
Log:
HHH-530 : followup on parameter handling
Modified: core/trunk/core/src/main/antlr/sql-gen.g
===================================================================
--- core/trunk/core/src/main/antlr/sql-gen.g 2008-10-08 04:12:32 UTC (rev 15267)
+++ core/trunk/core/src/main/antlr/sql-gen.g 2008-10-08 04:13:07 UTC (rev 15268)
@@ -213,7 +213,7 @@
| aggregate
| c:constant { out(c); }
| arithmeticExpr
- | PARAM { out("?"); }
+ | param:PARAM { out(param); }
| sn:SQL_NODE { out(sn); }
| { out("("); } selectStatement { out(")"); }
;
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2008-10-08 04:12:32 UTC (rev 15267)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2008-10-08 04:13:07 UTC (rev 15268)
@@ -45,7 +45,6 @@
import org.hibernate.sql.Select;
import org.hibernate.sql.SelectFragment;
import org.hibernate.util.StringHelper;
-import org.hibernate.util.EmptyIterator;
import antlr.RecognitionException;
import antlr.collections.AST;
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java 2008-10-08 04:12:32 UTC (rev 15267)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java 2008-10-08 04:13:07 UTC (rev 15268)
@@ -131,9 +131,10 @@
try {
try {
ps = session.getBatcher().prepareStatement( idInsertSelect );
- int parameterStart = getWalker().getNumberOfParametersInSetClause();
- List allParams = getIdSelectParameterSpecifications();
- Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
+// int parameterStart = getWalker().getNumberOfParametersInSetClause();
+// List allParams = getIdSelectParameterSpecifications();
+// Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
+ Iterator whereParams = getIdSelectParameterSpecifications().iterator();
int sum = 1; // jdbc params are 1-based
while ( whereParams.hasNext() ) {
sum += ( ( ParameterSpecification ) whereParams.next() ).bind( ps, parameters, session, sum );
16 years, 2 months
Hibernate SVN: r15267 - in core/branches/Branch_3_3/core/src/main: java/org/hibernate/hql/ast/exec and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-08 00:12:32 -0400 (Wed, 08 Oct 2008)
New Revision: 15267
Modified:
core/branches/Branch_3_3/core/src/main/antlr/sql-gen.g
core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
Log:
HHH-530 : followup on parameter handling
Modified: core/branches/Branch_3_3/core/src/main/antlr/sql-gen.g
===================================================================
--- core/branches/Branch_3_3/core/src/main/antlr/sql-gen.g 2008-10-08 03:13:08 UTC (rev 15266)
+++ core/branches/Branch_3_3/core/src/main/antlr/sql-gen.g 2008-10-08 04:12:32 UTC (rev 15267)
@@ -213,7 +213,7 @@
| aggregate
| c:constant { out(c); }
| arithmeticExpr
- | PARAM { out("?"); }
+ | param:PARAM { out(param); }
| sn:SQL_NODE { out(sn); }
| { out("("); } selectStatement { out(")"); }
;
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2008-10-08 03:13:08 UTC (rev 15266)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java 2008-10-08 04:12:32 UTC (rev 15267)
@@ -45,7 +45,6 @@
import org.hibernate.sql.Select;
import org.hibernate.sql.SelectFragment;
import org.hibernate.util.StringHelper;
-import org.hibernate.util.EmptyIterator;
import antlr.RecognitionException;
import antlr.collections.AST;
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java 2008-10-08 03:13:08 UTC (rev 15266)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java 2008-10-08 04:12:32 UTC (rev 15267)
@@ -131,9 +131,10 @@
try {
try {
ps = session.getBatcher().prepareStatement( idInsertSelect );
- int parameterStart = getWalker().getNumberOfParametersInSetClause();
- List allParams = getIdSelectParameterSpecifications();
- Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
+// int parameterStart = getWalker().getNumberOfParametersInSetClause();
+// List allParams = getIdSelectParameterSpecifications();
+// Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
+ Iterator whereParams = getIdSelectParameterSpecifications().iterator();
int sum = 1; // jdbc params are 1-based
while ( whereParams.hasNext() ) {
sum += ( ( ParameterSpecification ) whereParams.next() ).bind( ps, parameters, session, sum );
16 years, 2 months
Hibernate SVN: r15266 - core/trunk/core/src/main/java/org/hibernate/hql/ast/tree.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-07 23:13:08 -0400 (Tue, 07 Oct 2008)
New Revision: 15266
Modified:
core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java
Log:
HHH-3510 : HQL SQLFunction replacement not occuring when HQL text has no parenthesis (rollback)
Modified: core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java 2008-10-08 03:06:23 UTC (rev 15265)
+++ core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java 2008-10-08 03:13:08 UTC (rev 15266)
@@ -27,6 +27,7 @@
import antlr.SemanticException;
import antlr.collections.AST;
import org.hibernate.QueryException;
+import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.hql.antlr.SqlTokenTypes;
import org.hibernate.hql.ast.util.ColumnHelper;
import org.hibernate.persister.collection.QueryableCollection;
@@ -289,7 +290,8 @@
if ( fe != null ) {
return fe.getDataType();
}
- return null;
+ SQLFunction sf = getWalker().getSessionFactoryHelper().findSQLFunction( getText() );
+ return sf == null ? null : sf.getReturnType( null, null );
}
public void setScalarColumnText(int i) throws SemanticException {
16 years, 2 months
Hibernate SVN: r15265 - in validator/trunk: validation-api/src/main/java/javax/validation and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-10-07 23:06:23 -0400 (Tue, 07 Oct 2008)
New Revision: 15265
Added:
validator/trunk/validation-api/src/main/java/javax/validation/ReportAsSingleInvalidConstraint.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java
Log:
BVAL-31 add isReportAsSingleInvalidConstraint
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2008-10-07 21:23:27 UTC (rev 15264)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2008-10-08 03:06:23 UTC (rev 15265)
@@ -29,6 +29,7 @@
import javax.validation.Constraint;
import javax.validation.ConstraintDescriptor;
import javax.validation.ValidationException;
+import javax.validation.ReportAsSingleInvalidConstraint;
/**
* Describe a single constraint.
@@ -36,10 +37,11 @@
* @author Emmanuel Bernard
*/
public class ConstraintDescriptorImpl implements ConstraintDescriptor {
- private Annotation annotation;
- private Constraint constraintImplementation;
- private Set<String> contexts;
- private Map<String, Object> parameters;
+ private final Annotation annotation;
+ private final Constraint constraintImplementation;
+ private final Set<String> contexts;
+ private final Map<String, Object> parameters;
+ private final boolean isReportAsSingleInvalidConstraint;
public ConstraintDescriptorImpl(Annotation annotation, String[] contexts, Constraint validator) {
@@ -51,6 +53,9 @@
this.contexts.addAll( Arrays.asList( contexts ) );
this.constraintImplementation = validator;
this.parameters = getAnnotationParameters( annotation );
+ this.isReportAsSingleInvalidConstraint = annotation.annotationType().isAnnotationPresent(
+ ReportAsSingleInvalidConstraint.class
+ );
}
/**
@@ -87,6 +92,10 @@
return Collections.emptySet();
}
+ public boolean isReportAsSingleInvalidConstraint() {
+ return isReportAsSingleInvalidConstraint;
+ }
+
private Map<String, Object> getAnnotationParameters(Annotation annotation) {
Method[] declaredMethods = annotation.annotationType().getDeclaredMethods();
Map<String, Object> parameters = new HashMap<String, Object>( declaredMethods.length );
Modified: validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2008-10-07 21:23:27 UTC (rev 15264)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2008-10-08 03:06:23 UTC (rev 15265)
@@ -31,7 +31,7 @@
/**
* Returns the annotation describing the constraint declaration.
* If a composing constraint, parameter values are reflecting
- * the overridden parameters form the main constraint
+ * the overridden parameters from the main constraint
*
* @return The annotation for this constraint.
*/
@@ -66,4 +66,9 @@
* @return a set of ConstraintDescriptor object or an empty set
*/
Set<ConstraintDescriptor> getComposingConstraints();
+
+ /**
+ * @return true if the constraint is annotated with @ReportAsSingleInvalidConstraint
+ */
+ boolean isReportAsSingleInvalidConstraint();
}
Modified: validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java 2008-10-07 21:23:27 UTC (rev 15264)
+++ validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java 2008-10-08 03:06:23 UTC (rev 15265)
@@ -1,6 +1,11 @@
package javax.validation;
import java.lang.annotation.Annotation;
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
/**
* Mark a parameter as overriding the parameter of a composing constraint.
@@ -8,6 +13,7 @@
*
* @author Emmanuel Bernard
*/
+@Retention(RUNTIME)
public @interface OverridesParameter {
/**
* constraint type the parameter is overriding
@@ -15,7 +21,8 @@
Class<? extends Annotation> constraint();
/**
- * name of constraint parameter overridden
+ * name of constraint parameter overridden
+ * Defaults to the name of the parameter hosting the annotation
*/
String parameter();
Added: validator/trunk/validation-api/src/main/java/javax/validation/ReportAsSingleInvalidConstraint.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ReportAsSingleInvalidConstraint.java (rev 0)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ReportAsSingleInvalidConstraint.java 2008-10-08 03:06:23 UTC (rev 15265)
@@ -0,0 +1,18 @@
+package javax.validation;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
+
+/**
+ * A constraint annotation annotated with ReportAsSingleInvalidConstraint
+ * will return the composed annotation error report if any of the composing annotations
+ * fail. The error reports of each individual composing constraint is ignored.
+ *
+ * @author Emmanuel Bernard
+ */
+@Target({ ANNOTATION_TYPE })
+@Retention(RUNTIME)
+public @interface ReportAsSingleInvalidConstraint {
+}
16 years, 2 months
Hibernate SVN: r15264 - validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-10-07 17:23:27 -0400 (Tue, 07 Oct 2008)
New Revision: 15264
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
Log:
BVAL-31 APIs for constraint composition
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2008-10-07 21:22:00 UTC (rev 15263)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/impl/ConstraintDescriptorImpl.java 2008-10-07 21:23:27 UTC (rev 15264)
@@ -82,6 +82,11 @@
return parameters;
}
+ public Set<ConstraintDescriptor> getComposingConstraints() {
+ //FIXME implement
+ return Collections.emptySet();
+ }
+
private Map<String, Object> getAnnotationParameters(Annotation annotation) {
Method[] declaredMethods = annotation.annotationType().getDeclaredMethods();
Map<String, Object> parameters = new HashMap<String, Object>( declaredMethods.length );
16 years, 2 months
Hibernate SVN: r15263 - validator/trunk/validation-api/src/main/java/javax/validation.
by hibernate-commits@lists.jboss.org
Author: epbernard
Date: 2008-10-07 17:22:00 -0400 (Tue, 07 Oct 2008)
New Revision: 15263
Added:
validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java
validator/trunk/validation-api/src/main/java/javax/validation/constraints/
Modified:
validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
Log:
BVAL-31 APIs for constraint composition
Modified: validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2008-10-07 21:08:17 UTC (rev 15262)
+++ validator/trunk/validation-api/src/main/java/javax/validation/ConstraintDescriptor.java 2008-10-07 21:22:00 UTC (rev 15263)
@@ -29,6 +29,10 @@
*/
public interface ConstraintDescriptor {
/**
+ * Returns the annotation describing the constraint declaration.
+ * If a composing constraint, parameter values are reflecting
+ * the overridden parameters form the main constraint
+ *
* @return The annotation for this constraint.
*/
Annotation getAnnotation();
@@ -44,8 +48,22 @@
Constraint getConstraintImplementation();
/**
+ * Returns a map containing the annotation paramter names as keys and the annotation parameter values
+ * as value.
+ * If a composing constraint, parameter values are reflecting
+ * the overridden parameters form the main constraint
+ *
* @return Returns a map containing the annotation paramter names as keys and the annotation parameter values
* as value.
*/
Map<String, Object> getParameters();
+
+ /**
+ * Return a set of ConstraintDescriptors. Each ConstraintDescriptor describes a composing
+ * constraint. ConstraintDescriptor instances of composing constraints reflect overridden
+ * parameter values in #getParameters() and #getAnnotation()
+ *
+ * @return a set of ConstraintDescriptor object or an empty set
+ */
+ Set<ConstraintDescriptor> getComposingConstraints();
}
Added: validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java (rev 0)
+++ validator/trunk/validation-api/src/main/java/javax/validation/OverridesParameter.java 2008-10-07 21:22:00 UTC (rev 15263)
@@ -0,0 +1,31 @@
+package javax.validation;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Mark a parameter as overriding the parameter of a composing constraint.
+ * Both parameter must share the same type.
+ *
+ * @author Emmanuel Bernard
+ */
+public @interface OverridesParameter {
+ /**
+ * constraint type the parameter is overriding
+ */
+ Class<? extends Annotation> constraint();
+
+ /**
+ * name of constraint parameter overridden
+ */
+ String parameter();
+
+ /**
+ * index of the targetted constraint declaration when using
+ * multiple constraints of the same type.
+ * The index represent the index of the constraint in the value() array.
+ *
+ * By default, no index is defined and the single constraint declaration
+ * is targeted
+ */
+ int index() default -1;
+}
16 years, 2 months
Hibernate SVN: r15262 - in core/patches/v313_HHH-2397: src/org/hibernate/cfg and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: cbredesen
Date: 2008-10-07 17:08:17 -0400 (Tue, 07 Oct 2008)
New Revision: 15262
Modified:
core/patches/v313_HHH-2397/build.xml
core/patches/v313_HHH-2397/src/org/hibernate/cfg/Environment.java
Log:
HHH-2397 changed version strings
Modified: core/patches/v313_HHH-2397/build.xml
===================================================================
--- core/patches/v313_HHH-2397/build.xml 2008-10-07 20:47:28 UTC (rev 15261)
+++ core/patches/v313_HHH-2397/build.xml 2008-10-07 21:08:17 UTC (rev 15262)
@@ -18,7 +18,7 @@
<property name="name2" value="hibernate3"/>
<property name="version.major" value="3"/>
<property name="version.minor" value="1"/>
- <property name="version.patchlevel" value="3"/>
+ <property name="version.patchlevel" value="3_HHH-2397"/>
<property name="version.sansPatchLevel" value="${version.major}.${version.minor}"/>
<property name="version.full" value="${version.sansPatchLevel}.${version.patchlevel}"/>
<property name="fullname" value="${name}-${version.full}"/>
Modified: core/patches/v313_HHH-2397/src/org/hibernate/cfg/Environment.java
===================================================================
--- core/patches/v313_HHH-2397/src/org/hibernate/cfg/Environment.java 2008-10-07 20:47:28 UTC (rev 15261)
+++ core/patches/v313_HHH-2397/src/org/hibernate/cfg/Environment.java 2008-10-07 21:08:17 UTC (rev 15262)
@@ -152,7 +152,7 @@
*/
public final class Environment {
- public static final String VERSION = "3.1.3";
+ public static final String VERSION = "3.1.3_HHH-2397";
/**
* <tt>ConnectionProvider</tt> implementor to use when obtaining connections
16 years, 2 months
Hibernate SVN: r15261 - core/patches/v313_HHH-2397/src/org/hibernate/id.
by hibernate-commits@lists.jboss.org
Author: cbredesen
Date: 2008-10-07 16:47:28 -0400 (Tue, 07 Oct 2008)
New Revision: 15261
Modified:
core/patches/v313_HHH-2397/src/org/hibernate/id/TableHiLoGenerator.java
Log:
HHH-2397
Modified: core/patches/v313_HHH-2397/src/org/hibernate/id/TableHiLoGenerator.java
===================================================================
--- core/patches/v313_HHH-2397/src/org/hibernate/id/TableHiLoGenerator.java 2008-10-07 20:09:58 UTC (rev 15260)
+++ core/patches/v313_HHH-2397/src/org/hibernate/id/TableHiLoGenerator.java 2008-10-07 20:47:28 UTC (rev 15261)
@@ -54,11 +54,12 @@
throws HibernateException {
if (maxLo < 2) {
//keep the behavior consistent even for boundary usages
- int val = ( (Integer) super.generate(session, obj) ).intValue();
+ long val = ( (Number) super.generate(session, obj) ).longValue();
+ if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
return IdentifierGeneratorFactory.createNumber( val, returnClass );
}
if (lo>maxLo) {
- int hival = ( (Integer) super.generate(session, obj) ).intValue();
+ long hival = ( (Number) super.generate(session, obj) ).longValue();
lo = (hival == 0) ? 1 : 0;
hi = hival * (maxLo+1);
log.debug("new hi value: " + hival);
16 years, 2 months
Hibernate SVN: r15260 - core/patches.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-07 16:09:58 -0400 (Tue, 07 Oct 2008)
New Revision: 15260
Added:
core/patches/v313_HHH-2397/
Log:
Creating patch for 3.1.3 + HHH-2397
Copied: core/patches/v313_HHH-2397 (from rev 15259, core/tags/v313)
16 years, 2 months
Hibernate SVN: r15259 - in core/branches/Branch_3_3: core/src/main/java/org/hibernate/impl and 4 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2008-10-07 11:56:16 -0400 (Tue, 07 Oct 2008)
New Revision: 15259
Added:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/EntityNameResolver.java
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/Customer.hbm.xml
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/ImprovedTuplizerDynamicEntityTest.java
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionImpl.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java
Log:
HHH-3515 : EntityNameResolver
Added: core/branches/Branch_3_3/core/src/main/java/org/hibernate/EntityNameResolver.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/EntityNameResolver.java (rev 0)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/EntityNameResolver.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -0,0 +1,42 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate;
+
+/**
+ * Contract for resolving an entity-name from a given entity instance.
+ *
+ * @author Steve Ebersole
+ */
+public interface EntityNameResolver {
+ /**
+ * Given an entity instance, determine its entity-name.
+ *
+ * @param entity The entity instance.
+ *
+ * @return The corresponding entity-name, or null if this impl does not know how to perform resolution
+ * for the given entity instance.
+ */
+ public String resolveEntityName(Object entity);
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -39,6 +39,7 @@
import java.util.Map;
import java.util.Properties;
import java.util.Set;
+import java.util.LinkedHashSet;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
@@ -58,6 +59,9 @@
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.SessionFactoryObserver;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.tuple.entity.EntityTuplizer;
import org.hibernate.cache.CacheKey;
import org.hibernate.cache.CollectionRegion;
import org.hibernate.cache.EntityRegion;
@@ -113,6 +117,7 @@
import org.hibernate.type.Type;
import org.hibernate.util.CollectionHelper;
import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.EmptyIterator;
/**
@@ -172,6 +177,7 @@
private final transient EntityNotFoundDelegate entityNotFoundDelegate;
private final transient SQLFunctionRegistry sqlFunctionRegistry;
private final transient SessionFactoryObserver observer;
+ private final transient HashMap entityNameResolvers = new HashMap();
private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );
@@ -319,11 +325,15 @@
// after *all* persisters and named queries are registered
Iterator iter = entityPersisters.values().iterator();
while ( iter.hasNext() ) {
- ( (EntityPersister) iter.next() ).postInstantiate();
+ final EntityPersister persister = ( ( EntityPersister ) iter.next() );
+ persister.postInstantiate();
+ registerEntityNameResolvers( persister );
+
}
iter = collectionPersisters.values().iterator();
while ( iter.hasNext() ) {
- ( (CollectionPersister) iter.next() ).postInstantiate();
+ final CollectionPersister persister = ( ( CollectionPersister ) iter.next() );
+ persister.postInstantiate();
}
//JNDI + Serialization:
@@ -415,6 +425,41 @@
this.observer.sessionFactoryCreated( this );
}
+ private void registerEntityNameResolvers(EntityPersister persister) {
+ Iterator itr = persister.getEntityMetamodel().getTuplizerMapping().iterateTuplizers();
+ while ( itr.hasNext() ) {
+ final EntityTuplizer tuplizer = ( EntityTuplizer ) itr.next();
+ registerEntityNameResolvers( tuplizer );
+ }
+ }
+
+ private void registerEntityNameResolvers(EntityTuplizer tuplizer) {
+ EntityNameResolver[] resolvers = tuplizer.getEntityNameResolvers();
+ if ( resolvers == null ) {
+ return;
+ }
+
+ for ( int i = 0; i < resolvers.length; i++ ) {
+ registerEntityNameResolver( resolvers[i], tuplizer.getEntityMode() );
+ }
+ }
+
+ public void registerEntityNameResolver(EntityNameResolver resolver, EntityMode entityMode) {
+ LinkedHashSet resolversForMode = ( LinkedHashSet ) entityNameResolvers.get( entityMode );
+ if ( resolversForMode == null ) {
+ resolversForMode = new LinkedHashSet();
+ entityNameResolvers.put( entityMode, resolversForMode );
+ }
+ resolversForMode.add( resolver );
+ }
+
+ public Iterator iterateEntityNameResolvers(EntityMode entityMode) {
+ Set actualEntityNameResolvers = ( Set ) entityNameResolvers.get( entityMode );
+ return actualEntityNameResolvers == null
+ ? EmptyIterator.INSTANCE
+ : actualEntityNameResolvers.iterator();
+ }
+
public QueryPlanCache getQueryPlanCache() {
return queryPlanCache;
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionImpl.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/impl/SessionImpl.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -66,6 +66,7 @@
import org.hibernate.Transaction;
import org.hibernate.TransientObjectException;
import org.hibernate.UnresolvableObjectException;
+import org.hibernate.EntityNameResolver;
import org.hibernate.collection.PersistentCollection;
import org.hibernate.engine.ActionQueue;
import org.hibernate.engine.CollectionEntry;
@@ -139,7 +140,7 @@
*
* @author Gavin King
*/
-public final class SessionImpl extends AbstractSessionImpl
+public final class SessionImpl extends AbstractSessionImpl
implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
// todo : need to find a clean way to handle the "event source" role
@@ -175,6 +176,30 @@
private transient Session rootSession;
private transient Map childSessionsByEntityMode;
+ private EntityNameResolver entityNameResolver = new EntityNameResolver() {
+ public String resolveEntityName(Object entity) {
+ String entityName = interceptor.getEntityName( entity );
+ if ( entityName != null ) {
+ return entityName;
+ }
+
+ Iterator itr = factory.iterateEntityNameResolvers( entityMode );
+ while ( itr.hasNext() ) {
+ final EntityNameResolver resolver = ( EntityNameResolver ) itr.next();
+ entityName = resolver.resolveEntityName( entity );
+ if ( entityName != null ) {
+ break;
+ }
+ }
+ if ( entityName != null ) {
+ return entityName;
+ }
+
+ // the old-time stand-by...
+ return entity.getClass().getName();
+ }
+ };
+
/**
* Constructor used in building "child sessions".
*
@@ -1789,23 +1814,7 @@
public String guessEntityName(Object object) throws HibernateException {
errorIfClosed();
- String entity = interceptor.getEntityName( object );
- if ( entity == null ) {
- if ( object instanceof Map ) {
- entity = (String) ( (Map) object ).get( DynamicMapInstantiator.KEY );
- if ( entity == null ) {
- throw new HibernateException( "could not determine type of dynamic entity" );
- }
- }
- else if ( object instanceof Element ) {
- // TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
- entity = ( (Element) object ).getName();
- }
- else {
- entity = object.getClass().getName();
- }
- }
- return entity;
+ return entityNameResolver.resolveEntityName( object );
}
public void cancelQuery() throws HibernateException {
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -133,7 +133,6 @@
private final boolean isLazyPropertiesCacheable;
private final CacheEntryStructure cacheEntryStructure;
private final EntityMetamodel entityMetamodel;
- private final Map entityNameBySubclass = new HashMap();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private final String[] rootTableKeyColumnNames;
@@ -455,15 +454,6 @@
(CacheEntryStructure) new UnstructuredCacheEntry();
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
-
- if ( persistentClass.hasPojoRepresentation() ) {
- //TODO: this is currently specific to pojos, but need to be available for all entity-modes
- Iterator iter = persistentClass.getSubclassIterator();
- while ( iter.hasNext() ) {
- PersistentClass pc = ( PersistentClass ) iter.next();
- entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() );
- }
- }
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int batch = persistentClass.getBatchSize();
@@ -3254,10 +3244,6 @@
return entityMetamodel.getEntityType();
}
- private String getSubclassEntityName(Class clazz) {
- return ( String ) entityNameBySubclass.get( clazz );
- }
-
public boolean isPolymorphic() {
return entityMetamodel.isPolymorphic();
}
@@ -3646,29 +3632,17 @@
getTuplizer( entityMode ).resetIdentifier( entity, currentId, currentVersion );
}
- public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode) {
+ public EntityPersister getSubclassEntityPersister(
+ Object instance,
+ SessionFactoryImplementor factory,
+ EntityMode entityMode) {
if ( !hasSubclasses() ) {
return this;
}
else {
- // TODO : really need a way to do something like :
- // getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)
- Class clazz = instance.getClass();
- if ( clazz == getMappedClass( entityMode ) ) {
- return this;
- }
- else {
- String subclassEntityName = getSubclassEntityName( clazz );
- if ( subclassEntityName == null ) {
- throw new HibernateException(
- "instance not of expected entity type: " + clazz.getName() +
- " is not a: " + getEntityName()
- );
- }
- else {
- return factory.getEntityPersister( subclassEntityName );
- }
- }
+ final String concreteEntityName = getTuplizer( entityMode )
+ .determineConcreteSubclassEntityName( instance, factory );
+ return factory.getEntityPersister( concreteEntityName );
}
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -668,15 +668,35 @@
public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode);
/**
- * Set the identifier and version of the given instance back
- * to its "unsaved" value, returning the id
- * @param currentId TODO
- * @param currentVersion TODO
+ * Set the identifier and version of the given instance back to its "unsaved" value.
+ *
+ * @param entity The entity instance
+ * @param currentId The currently assigned identifier value.
+ * @param currentVersion The currently assigned version value.
+ * @param entityMode The entity mode represented by the entity instance.
*/
public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode);
/**
- * Get the persister for an instance of this class or a subclass
+ * A request has already identified the entity-name of this persister as the mapping for the given instance.
+ * However, we still need to account for possible subclassing and potentially re-route to the more appropriate
+ * persister.
+ * <p/>
+ * For example, a request names <tt>Animal</tt> as the entity-name which gets resolved to this persister. But the
+ * actual instance is really an instance of <tt>Cat</tt> which is a subclass of <tt>Animal</tt>. So, here the
+ * <tt>Animal</tt> persister is being asked to return the persister specific to <tt>Cat</tt>.
+ * <p/>
+ * It is also possible that the instance is actually an <tt>Animal</tt> instance in the above example in which
+ * case we would retrn <tt>this</tt> from this method.
+ *
+ * @param instance The entity instance
+ * @param factory Reference to the SessionFactory
+ * @param entityMode The entity mode represented by the entity instance.
+ *
+ * @return The appropriate persister
+ *
+ * @throws HibernateException Indicates that instance was deemed to not be a subclass of the entity mapped by
+ * this persister.
*/
public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode);
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -74,13 +74,6 @@
/**
- * Return the entity-mode handled by this tuplizer instance.
- *
- * @return The entity-mode
- */
- protected abstract EntityMode getEntityMode();
-
- /**
* Build an appropriate Getter for the given property.
*
* @param mappedProperty The property to be accessed via the built Getter.
@@ -326,7 +319,6 @@
* @return The property value extracted.
*/
protected Object getComponentValue(ComponentType type, Object component, String propertyPath) {
-
int loc = propertyPath.indexOf('.');
String basePropertyName = loc>0 ?
propertyPath.substring(0, loc) : propertyPath;
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -35,6 +35,8 @@
import org.hibernate.property.Setter;
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.Dom4jInstantiator;
import org.hibernate.type.AbstractComponentType;
@@ -44,8 +46,9 @@
import java.io.Serializable;
import java.util.HashSet;
-import java.util.Set;
import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
/**
* An {@link EntityTuplizer} specific to the dom4j entity mode.
@@ -57,17 +60,21 @@
static final Logger log = LoggerFactory.getLogger( Dom4jEntityTuplizer.class );
- private Set subclassNodeNames = new HashSet();
+ private Map inheritenceNodeNameMap = new HashMap();
Dom4jEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
- super(entityMetamodel, mappedEntity);
+ super( entityMetamodel, mappedEntity );
+ inheritenceNodeNameMap.put( mappedEntity.getNodeName(), mappedEntity.getEntityName() );
Iterator itr = mappedEntity.getSubclassClosureIterator();
while( itr.hasNext() ) {
final PersistentClass mapping = ( PersistentClass ) itr.next();
- subclassNodeNames.add( mapping.getNodeName() );
+ inheritenceNodeNameMap.put( mapping.getNodeName(), mapping.getEntityName() );
}
}
+ /**
+ * {@inheritDoc}
+ */
public EntityMode getEntityMode() {
return EntityMode.DOM4J;
}
@@ -85,18 +92,30 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
}
+ /**
+ * {@inheritDoc}
+ */
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
}
+ /**
+ * {@inheritDoc}
+ */
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
return new Dom4jInstantiator( persistentClass );
}
+ /**
+ * {@inheritDoc}
+ */
public Serializable getIdentifier(Object entityOrId) throws HibernateException {
if (entityOrId instanceof Element) {
return super.getIdentifier(entityOrId);
@@ -107,6 +126,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
HashSet proxyInterfaces = new HashSet();
proxyInterfaces.add( HibernateProxy.class );
@@ -132,15 +154,73 @@
return pf;
}
+ /**
+ * {@inheritDoc}
+ */
public Class getMappedClass() {
return Element.class;
}
+ /**
+ * {@inheritDoc}
+ */
public Class getConcreteProxyClass() {
return Element.class;
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isInstrumented() {
return false;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ public EntityNameResolver[] getEntityNameResolvers() {
+ return new EntityNameResolver[] { new BasicEntityNameResolver( getEntityName(), inheritenceNodeNameMap ) };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
+ return ( String ) inheritenceNodeNameMap.get( extractNodeName( ( Element ) entityInstance ) );
+ }
+
+ public static String extractNodeName(Element element) {
+ return element.getName();
+ }
+
+ public static class BasicEntityNameResolver implements EntityNameResolver {
+ private final String rootEntityName;
+ private final Map nodeNameToEntityNameMap;
+
+ public BasicEntityNameResolver(String rootEntityName, Map nodeNameToEntityNameMap) {
+ this.rootEntityName = rootEntityName;
+ this.nodeNameToEntityNameMap = nodeNameToEntityNameMap;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String resolveEntityName(Object entity) {
+ return ( String ) nodeNameToEntityNameMap.get( extractNodeName( ( Element ) entity ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean equals(Object obj) {
+ return rootEntityName.equals( ( ( BasicEntityNameResolver ) obj ).rootEntityName );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int hashCode() {
+ return rootEntityName.hashCode();
+ }
+ }
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -28,6 +28,8 @@
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.DynamicMapInstantiator;
import org.hibernate.mapping.PersistentClass;
@@ -112,4 +114,37 @@
public boolean isInstrumented() {
return false;
}
+
+ public EntityNameResolver[] getEntityNameResolvers() {
+ return new EntityNameResolver[] { BasicEntityNameResolver.INSTANCE };
+ }
+
+ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
+ // TODO : do we need an explicit isInstance check here, or is that asserted prior to here?
+ return extractEmbeddedEntityName( ( Map ) entityInstance );
+ }
+
+ public static String extractEmbeddedEntityName(Map entity) {
+ return ( String ) entity.get( DynamicMapInstantiator.KEY );
+ }
+
+ public static class BasicEntityNameResolver implements EntityNameResolver {
+ public static final BasicEntityNameResolver INSTANCE = new BasicEntityNameResolver();
+
+ public String resolveEntityName(Object entity) {
+ final String entityName = extractEmbeddedEntityName( ( Map ) entity );
+ if ( entityName == null ) {
+ throw new HibernateException( "Could not determine type of dynamic map entity" );
+ }
+ return entityName;
+ }
+
+ public boolean equals(Object obj) {
+ return getClass().equals( obj.getClass() );
+ }
+
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+ }
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -122,21 +122,10 @@
private final boolean inherited;
private final boolean hasSubclasses;
private final Set subclassEntityNames = new HashSet();
+ private final Map entityNameByInheritenceClassNameMap = new HashMap();
private final EntityEntityModeToTuplizerMapping tuplizerMapping;
- public EntityTuplizer getTuplizer(EntityMode entityMode) {
- return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
- }
-
- public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
- return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
- }
-
- public EntityMode guessEntityMode(Object object) {
- return tuplizerMapping.guessEntityMode( object );
- }
-
public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
@@ -322,6 +311,15 @@
}
subclassEntityNames.add( name );
+ if ( persistentClass.hasPojoRepresentation() ) {
+ entityNameByInheritenceClassNameMap.put( persistentClass.getMappedClass(), persistentClass.getEntityName() );
+ iter = persistentClass.getSubclassIterator();
+ while ( iter.hasNext() ) {
+ final PersistentClass pc = ( PersistentClass ) iter.next();
+ entityNameByInheritenceClassNameMap.put( pc.getMappedClass(), pc.getEntityName() );
+ }
+ }
+
tuplizerMapping = new EntityEntityModeToTuplizerMapping( persistentClass, this );
}
@@ -395,6 +393,22 @@
}
}
+ public EntityEntityModeToTuplizerMapping getTuplizerMapping() {
+ return tuplizerMapping;
+ }
+
+ public EntityTuplizer getTuplizer(EntityMode entityMode) {
+ return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
+ }
+
+ public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
+ return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
+ }
+
+ public EntityMode guessEntityMode(Object object) {
+ return tuplizerMapping.guessEntityMode( object );
+ }
+
public int[] getNaturalIdentifierProperties() {
return naturalIdPropertyNumbers;
}
@@ -555,6 +569,16 @@
return isAbstract;
}
+ /**
+ * Return the entity-name mapped to the given class within our inheritence hierarchy, if any.
+ *
+ * @param inheritenceClass The class for which to resolve the entity-name.
+ * @return The mapped entity-name, or null if no such mapping was found.
+ */
+ public String findEntityNameByEntityClass(Class inheritenceClass) {
+ return ( String ) entityNameByInheritenceClassNameMap.get( inheritenceClass.getName() );
+ }
+
public String toString() {
return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -28,8 +28,11 @@
import java.util.Map;
import org.hibernate.HibernateException;
+import org.hibernate.EntityNameResolver;
+import org.hibernate.EntityMode;
import org.hibernate.tuple.Tuplizer;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
/**
* Defines further responsibilities reagarding tuplization based on
@@ -42,6 +45,12 @@
* @author Steve Ebersole
*/
public interface EntityTuplizer extends Tuplizer {
+ /**
+ * Return the entity-mode handled by this tuplizer instance.
+ *
+ * @return The entity-mode
+ */
+ public EntityMode getEntityMode();
/**
* Create an entity instance initialized with the given identifier.
@@ -176,11 +185,11 @@
*/
public boolean isValidatableImplementor();
- // TODO: getConcreteProxyClass() is solely used (externally) to perform narrowProxy()
- // would be great to fully encapsulate that narrowProxy() functionality within the
- // Tuplizer, itself, with a Tuplizer.narrowProxy(..., PersistentContext) method
/**
* Returns the java class to which generated proxies will be typed.
+ * <p/>
+ * todo : look at fully encapsulating {@link org.hibernate.engine.PersistenceContext#narrowProxy} here,
+ * since that is the only external use of this method
*
* @return The java class to which generated proxies will be typed
*/
@@ -198,4 +207,35 @@
* Is it an instrumented POJO?
*/
public boolean isInstrumented();
+
+ /**
+ * Get any {@link EntityNameResolver EntityNameResolvers} associated with this {@link Tuplizer}.
+ *
+ * @return The associated resolvers. May be null or empty.
+ */
+ public EntityNameResolver[] getEntityNameResolvers();
+
+ /**
+ * Given an entity instance, determine the most appropriate (most targeted) entity-name which represents it.
+ * This is called in situations where we already know an entity name for the given entityInstance; we are being
+ * asked to determine if there is a more appropriate entity-name to use, specifically within an inheritence
+ * hierarchy.
+ * <p/>
+ * For example, consider a case where a user calls <tt>session.update( "Animal", cat );</tt>. Here, the
+ * user has explicitly provided <tt>Animal</tt> as the entity-name. However, they have passed in an instance
+ * of <tt>Cat</tt> which is a subclass of <tt>Animal</tt>. In this case, we would return <tt>Cat</tt> as the
+ * entity-name.
+ * <p/>
+ * <tt>null</tt> may be returned from calls to this method. The meaining of <tt>null</tt> in that case is assumed
+ * to be that we should use whatever explicit entity-name the user provided (<tt>Animal</tt> rather than <tt>Cat</tt>
+ * in the example above).
+ *
+ * @param entityInstance The entity instance.
+ * @param factory Reference to the SessionFactory.
+ *
+ * @return The most appropriate entity name to use.
+ *
+ * @throws HibernateException If we are unable to determine an entity-name within the inheritence hierarchy.
+ */
+ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory);
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java 2008-10-07 15:54:42 UTC (rev 15258)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -36,6 +36,7 @@
import org.hibernate.EntityMode;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
+import org.hibernate.EntityNameResolver;
import org.hibernate.tuple.Instantiator;
import org.hibernate.tuple.PojoInstantiator;
import org.hibernate.bytecode.ReflectionOptimizer;
@@ -43,6 +44,7 @@
import org.hibernate.classic.Lifecycle;
import org.hibernate.classic.Validatable;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.intercept.FieldInterceptor;
import org.hibernate.intercept.FieldInterceptionHelper;
import org.hibernate.mapping.PersistentClass;
@@ -70,7 +72,7 @@
private final boolean lifecycleImplementor;
private final boolean validatableImplementor;
private final Set lazyPropertyNames = new HashSet();
- private ReflectionOptimizer optimizer;
+ private final ReflectionOptimizer optimizer;
public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
super( entityMetamodel, mappedEntity );
@@ -109,6 +111,9 @@
}
+ /**
+ * {@inheritDoc}
+ */
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
// determine the id getter and setter methods from the proxy interface (if any)
// determine all interfaces needed by the resulting proxy
@@ -199,11 +204,14 @@
}
protected ProxyFactory buildProxyFactoryInternal(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
- // TODO : YUCK!!! finx after HHH-1907 is complete
+ // TODO : YUCK!!! fix after HHH-1907 is complete
return Environment.getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
// return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
}
+ /**
+ * {@inheritDoc}
+ */
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
if ( optimizer == null ) {
return new PojoInstantiator( persistentClass, null );
@@ -213,6 +221,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
if ( !getEntityMetamodel().hasLazyProperties() && optimizer != null && optimizer.getAccessOptimizer() != null ) {
setPropertyValuesWithOptimizer( entity, values );
@@ -222,6 +233,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
public Object[] getPropertyValues(Object entity) throws HibernateException {
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
return getPropertyValuesWithOptimizer( entity );
@@ -231,6 +245,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) throws HibernateException {
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
return getPropertyValuesWithOptimizer( entity );
@@ -248,36 +265,60 @@
return optimizer.getAccessOptimizer().getPropertyValues( object );
}
+ /**
+ * {@inheritDoc}
+ */
public EntityMode getEntityMode() {
return EntityMode.POJO;
}
+ /**
+ * {@inheritDoc}
+ */
public Class getMappedClass() {
return mappedClass;
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isLifecycleImplementor() {
return lifecycleImplementor;
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isValidatableImplementor() {
return validatableImplementor;
}
+ /**
+ * {@inheritDoc}
+ */
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
return mappedProperty.getGetter( mappedEntity.getMappedClass() );
}
+ /**
+ * {@inheritDoc}
+ */
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
return mappedProperty.getSetter( mappedEntity.getMappedClass() );
}
+ /**
+ * {@inheritDoc}
+ */
public Class getConcreteProxyClass() {
return proxyInterface;
}
//TODO: need to make the majority of this functionality into a top-level support class for custom impl support
+ /**
+ * {@inheritDoc}
+ */
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
if ( isInstrumented() ) {
Set lazyProps = lazyPropertiesAreUnfetched && getEntityMetamodel().hasLazyProperties() ?
@@ -288,6 +329,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
public boolean hasUninitializedLazyProperties(Object entity) {
if ( getEntityMetamodel().hasLazyProperties() ) {
FieldInterceptor callback = FieldInterceptionHelper.extractFieldInterceptor( entity );
@@ -298,8 +342,37 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
public boolean isInstrumented() {
return FieldInterceptionHelper.isInstrumented( getMappedClass() );
}
+ /**
+ * {@inheritDoc}
+ */
+ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
+ final Class concreteEntityClass = entityInstance.getClass();
+ if ( concreteEntityClass == getMappedClass() ) {
+ return getEntityName();
+ }
+ else {
+ String entityName = getEntityMetamodel().findEntityNameByEntityClass( concreteEntityClass );
+ if ( entityName == null ) {
+ throw new HibernateException(
+ "Unable to resolve entity name from Class [" + concreteEntityClass.getName() + "]"
+ + " expected instance/subclass of [" + getEntityName() + "]"
+ );
+ }
+ return entityName;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EntityNameResolver[] getEntityNameResolvers() {
+ return null;
+ }
}
Added: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/Customer.hbm.xml
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/Customer.hbm.xml (rev 0)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/Customer.hbm.xml 2008-10-07 15:56:16 UTC (rev 15259)
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ ~
+ -->
+
+<!DOCTYPE hibernate-mapping PUBLIC
+ "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+ "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping package="org.hibernate.test.dynamicentity">
+
+ <class name="Person" table="t_person" discriminator-value="person" abstract="false">
+ <tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <discriminator force="false"/>
+ <property name="name"/>
+
+ <many-to-one name="address" cascade="all" column="addr_id"/>
+
+ <set name="family" lazy="true" cascade="all">
+ <key column="pers_id"/>
+ <one-to-many class="Person"/>
+ </set>
+
+ <subclass name="Customer" discriminator-value="customer" abstract="false">
+ <tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
+ <many-to-one name="company" cascade="none" column="comp_id"/>
+ </subclass>
+ </class>
+
+ <class name="Company" table="t_company" abstract="false">
+ <tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="Address" table="t_address" abstract="false">
+ <tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="street"/>
+ <property name="city"/>
+ <property name="postalCode"/>
+ </class>
+
+</hibernate-mapping>
Added: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/ImprovedTuplizerDynamicEntityTest.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/ImprovedTuplizerDynamicEntityTest.java (rev 0)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/ImprovedTuplizerDynamicEntityTest.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -0,0 +1,149 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.dynamicentity.tuplizer2;
+
+import org.hibernate.test.dynamicentity.Company;
+import org.hibernate.test.dynamicentity.ProxyHelper;
+import org.hibernate.test.dynamicentity.Customer;
+import org.hibernate.test.dynamicentity.Address;
+import org.hibernate.test.dynamicentity.Person;
+import org.hibernate.Session;
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+import junit.framework.TestSuite;
+
+import java.util.HashSet;
+
+/**
+ * Demonstrates use of Tuplizers to allow the use of JDK
+ * {@link java.lang.reflect.Proxy dynamic proxies} as our
+ * domain model.
+ * <p/>
+ * Here we plug a custom Interceptor into the session simply to
+ * allow us to not have to explicitly supply the appropriate entity
+ * name to the Session calls.
+ *
+ * @author Steve Ebersole
+ */
+public class ImprovedTuplizerDynamicEntityTest extends FunctionalTestCase {
+ public ImprovedTuplizerDynamicEntityTest(String x) {
+ super( x );
+ }
+
+ public String[] getMappings() {
+ return new String[] { "dynamicentity/tuplizer2/Customer.hbm.xml" };
+ }
+
+ public void configure(Configuration cfg) {
+ super.configure( cfg );
+ }
+
+ public static TestSuite suite() {
+ return new FunctionalTestClassTestSuite( ImprovedTuplizerDynamicEntityTest.class );
+ }
+
+ public void testIt() {
+ // Test saving these dyna-proxies
+ Session session = openSession();
+ session.beginTransaction();
+ Company company = ProxyHelper.newCompanyProxy();
+ company.setName( "acme" );
+ session.save( company );
+ Customer customer = ProxyHelper.newCustomerProxy();
+ customer.setName( "Steve" );
+ customer.setCompany( company );
+ Address address = ProxyHelper.newAddressProxy();
+ address.setStreet( "somewhere over the rainbow" );
+ address.setCity( "lawerence, kansas" );
+ address.setPostalCode( "toto");
+ customer.setAddress( address );
+ customer.setFamily( new HashSet() );
+ Person son = ProxyHelper.newPersonProxy();
+ son.setName( "son" );
+ customer.getFamily().add( son );
+ Person wife = ProxyHelper.newPersonProxy();
+ wife.setName( "wife" );
+ customer.getFamily().add( wife );
+ session.save( customer );
+ session.getTransaction().commit();
+ session.close();
+
+ assertNotNull( "company id not assigned", company.getId() );
+ assertNotNull( "customer id not assigned", customer.getId() );
+ assertNotNull( "address id not assigned", address.getId() );
+ assertNotNull( "son:Person id not assigned", son.getId() );
+ assertNotNull( "wife:Person id not assigned", wife.getId() );
+
+ // Test loading these dyna-proxies, along with flush processing
+ session = openSession();
+ session.beginTransaction();
+ customer = ( Customer ) session.load( Customer.class, customer.getId() );
+ assertFalse( "should-be-proxy was initialized", Hibernate.isInitialized( customer ) );
+
+ customer.setName( "other" );
+ session.flush();
+ assertFalse( "should-be-proxy was initialized", Hibernate.isInitialized( customer.getCompany() ) );
+
+ session.refresh( customer );
+ assertEquals( "name not updated", "other", customer.getName() );
+ assertEquals( "company association not correct", "acme", customer.getCompany().getName() );
+
+ session.getTransaction().commit();
+ session.close();
+
+ // Test detached entity re-attachment with these dyna-proxies
+ customer.setName( "Steve" );
+ session = openSession();
+ session.beginTransaction();
+ session.update( customer );
+ session.flush();
+ session.refresh( customer );
+ assertEquals( "name not updated", "Steve", customer.getName() );
+ session.getTransaction().commit();
+ session.close();
+
+ // Test querying
+ session = openSession();
+ session.beginTransaction();
+ int count = session.createQuery( "from Customer" ).list().size();
+ assertEquals( "querying dynamic entity", 1, count );
+ session.clear();
+ count = session.createQuery( "from Person" ).list().size();
+ assertEquals( "querying dynamic entity", 3, count );
+ session.getTransaction().commit();
+ session.close();
+
+ // test deleteing
+ session = openSession();
+ session.beginTransaction();
+ session.delete( company );
+ session.delete( customer );
+ session.getTransaction().commit();
+ session.close();
+ }
+}
Added: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java (rev 0)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityInstantiator.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -0,0 +1,78 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.dynamicentity.tuplizer2;
+
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.test.dynamicentity.Customer;
+import org.hibernate.test.dynamicentity.ProxyHelper;
+import org.hibernate.test.dynamicentity.Company;
+import org.hibernate.test.dynamicentity.Address;
+import org.hibernate.test.dynamicentity.Person;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MyEntityInstantiator implements Instantiator {
+ private final String entityName;
+
+ public MyEntityInstantiator(String entityName) {
+ this.entityName = entityName;
+ }
+
+ public Object instantiate(Serializable id) {
+ if ( Person.class.getName().equals( entityName ) ) {
+ return ProxyHelper.newPersonProxy( id );
+ }
+ if ( Customer.class.getName().equals( entityName ) ) {
+ return ProxyHelper.newCustomerProxy( id );
+ }
+ else if ( Company.class.getName().equals( entityName ) ) {
+ return ProxyHelper.newCompanyProxy( id );
+ }
+ else if ( Address.class.getName().equals( entityName ) ) {
+ return ProxyHelper.newAddressProxy( id );
+ }
+ else {
+ throw new IllegalArgumentException( "unknown entity for instantiation [" + entityName + "]" );
+ }
+ }
+
+ public Object instantiate() {
+ return instantiate( null );
+ }
+
+ public boolean isInstance(Object object) {
+ try {
+ return ReflectHelper.classForName( entityName ).isInstance( object );
+ }
+ catch( Throwable t ) {
+ throw new HibernateException( "could not get handle to entity-name as interface : " + t );
+ }
+ }
+}
Added: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java (rev 0)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/dynamicentity/tuplizer2/MyEntityTuplizer.java 2008-10-07 15:56:16 UTC (rev 15259)
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.dynamicentity.tuplizer2;
+
+import org.hibernate.tuple.entity.PojoEntityTuplizer;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+import org.hibernate.test.dynamicentity.tuplizer.MyEntityInstantiator;
+import org.hibernate.test.dynamicentity.ProxyHelper;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.EntityNameResolver;
+
+/**
+ * @author Steve Ebersole
+ */
+public class MyEntityTuplizer extends PojoEntityTuplizer {
+
+ public MyEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
+ super( entityMetamodel, mappedEntity );
+ }
+
+ public EntityNameResolver[] getEntityNameResolvers() {
+ return new EntityNameResolver[] { MyEntityNameResolver.INSTANCE };
+ }
+
+ protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+ return new MyEntityInstantiator( persistentClass.getEntityName() );
+ }
+
+ public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
+ String entityName = ProxyHelper.extractEntityName( entityInstance );
+ if ( entityName == null ) {
+ entityName = super.determineConcreteSubclassEntityName( entityInstance, factory );
+ }
+ return entityName;
+ }
+
+ protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
+ // allows defining a custom proxy factory, which is responsible for
+ // generating lazy proxies for a given entity.
+ //
+ // Here we simply use the default...
+ return super.buildProxyFactory( persistentClass, idGetter, idSetter );
+ }
+
+ public static class MyEntityNameResolver implements EntityNameResolver {
+ public static final MyEntityNameResolver INSTANCE = new MyEntityNameResolver();
+
+ public String resolveEntityName(Object entity) {
+ return ProxyHelper.extractEntityName( entity );
+ }
+
+ public boolean equals(Object obj) {
+ return getClass().equals( obj.getClass() );
+ }
+
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+ }
+}
16 years, 2 months