Hibernate SVN: r15902 - in validator/trunk: hibernate-validator/src/main/java/org/hibernate/validation/engine and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-02-05 06:53:49 -0500 (Thu, 05 Feb 2009)
New Revision: 15902
Added:
validator/trunk/validation-api/src/main/java/javax/validation/AmbiguousConstraintUsageException.java
validator/trunk/validation-api/src/main/java/javax/validation/UnexpectedTypeForConstraintException.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Account.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/MultipleMinMax.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Bar.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java
validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
Log:
BVAL-99 Added exceptions
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id: SizeValidatorForString.java 15853 2009-02-02 15:42:10Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id: SizeValidatorForString.java 15853 2009-02-02 15:42:10Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id: SizeValidatorForString.java 15853 2009-02-02 15:42:10Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -22,9 +22,11 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import javax.validation.AmbiguousConstraintUsageException;
import javax.validation.ConstraintDescriptor;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorFactory;
+import javax.validation.UnexpectedTypeForConstraintException;
import javax.validation.ValidationException;
import org.slf4j.Logger;
@@ -168,11 +170,19 @@
Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes = ValidatorTypeHelper
.getValidatorsTypes( descriptor.getConstraintValidatorClasses() );
-
List<Class> assignableClasses = findAssingableClasses( valueClass, validatorsTypes );
resolveAssignableClasses( assignableClasses );
- if ( assignableClasses.size() != 1 ) {
+ verifyResolveWasUnique( valueClass, assignableClasses );
+
+ return validatorsTypes.get( assignableClasses.get( 0 ) );
+ }
+
+ private void verifyResolveWasUnique(Class valueClass, List<Class> assignableClasses) {
+ if ( assignableClasses.size() == 0 ) {
+ throw new UnexpectedTypeForConstraintException( "No validator could be found for type: " + valueClass.getName() );
+ }
+ else if ( assignableClasses.size() > 1 ) {
StringBuilder builder = new StringBuilder();
builder.append( "There are multiple validators which could validate the type " );
builder.append( valueClass );
@@ -182,10 +192,8 @@
builder.append( ", " );
}
builder.delete( builder.length() - 2, builder.length() );
- throw new ValidationException( builder.toString() );
+ throw new AmbiguousConstraintUsageException( builder.toString() );
}
-
- return validatorsTypes.get( assignableClasses.get( 0 ) );
}
private List<Class> findAssingableClasses(Class valueClass, Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes) {
@@ -213,7 +221,7 @@
* which are handled by at least one of the validators for the specified constraint.
*/
private void resolveAssignableClasses(List<Class> assignableClasses) {
- if ( assignableClasses.size() == 1 ) {
+ if ( assignableClasses.size() == 0 || assignableClasses.size() == 1 ) {
return;
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id: ValidatorImpl.java 15837 2009-01-30 15:49:57Z hardy.ferentschik $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ValidatorImpl.java
___________________________________________________________________
Name: svn:keywords
+ Id
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/Account.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/MultipleMinMax.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/MultipleMinMax.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/MultipleMinMax.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/eg/MultipleMinMax.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Bar.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Bar.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Bar.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -17,9 +17,21 @@
*/
package org.hibernate.validation.engine.validatorresolution;
+import javax.validation.constraints.Size;
+
/**
* @author Hardy Ferentschik
*/
public class Bar {
+ // validating Bar actually raises an UnexpectedTypeForConstraintException - @Size is not defined for Integer
+ @Size
+ private Integer value = 0;
+ public Integer getValue() {
+ return value;
+ }
+
+ public void setValue(Integer value) {
+ this.value = value;
+ }
}
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -18,11 +18,13 @@
package org.hibernate.validation.engine.validatorresolution;
import java.util.Set;
+import javax.validation.AmbiguousConstraintUsageException;
import javax.validation.ConstraintViolation;
-import javax.validation.ValidationException;
import javax.validation.Validator;
+import javax.validation.UnexpectedTypeForConstraintException;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.Test;
@@ -56,12 +58,26 @@
validator.validate( foo );
fail();
}
- catch ( ValidationException e ) {
+ catch ( AmbiguousConstraintUsageException e ) {
assertTrue( e.getMessage().startsWith( "There are multiple validators" ) );
}
}
@Test
+ public void testUnexpectedType() {
+ Validator validator = getValidator();
+
+ Bar bar = new Bar();
+ try {
+ validator.validate( bar );
+ fail();
+ }
+ catch ( UnexpectedTypeForConstraintException e ) {
+ assertEquals( "No validator could be found for type: java.lang.Integer", e.getMessage() );
+ }
+ }
+
+ @Test
public void testMultipleSizeValidators() {
Validator validator = getValidator();
Added: validator/trunk/validation-api/src/main/java/javax/validation/AmbiguousConstraintUsageException.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/AmbiguousConstraintUsageException.java (rev 0)
+++ validator/trunk/validation-api/src/main/java/javax/validation/AmbiguousConstraintUsageException.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -0,0 +1,44 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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 javax.validation;
+
+import javax.validation.ValidationException;
+
+/**
+ * Exception raised in the case that the constraint validator resolution returns more than one possible validators for
+ * a given type.
+ *
+ * @author Hardy Ferentschik
+ */
+public class AmbiguousConstraintUsageException extends ValidationException {
+ public AmbiguousConstraintUsageException(String message) {
+ super( message );
+ }
+
+ public AmbiguousConstraintUsageException() {
+ super();
+ }
+
+ public AmbiguousConstraintUsageException(String message, Throwable cause) {
+ super( message, cause );
+ }
+
+ public AmbiguousConstraintUsageException(Throwable cause) {
+ super( cause );
+ }
+}
Property changes on: validator/trunk/validation-api/src/main/java/javax/validation/AmbiguousConstraintUsageException.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java 2009-02-05 11:24:23 UTC (rev 15901)
+++ validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -1,4 +1,4 @@
-// $Id: Constraint.java 15817 2009-01-25 22:35:36Z epbernard $
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
Property changes on: validator/trunk/validation-api/src/main/java/javax/validation/Constraint.java
___________________________________________________________________
Name: svn:keywords
+ Id
Added: validator/trunk/validation-api/src/main/java/javax/validation/UnexpectedTypeForConstraintException.java
===================================================================
--- validator/trunk/validation-api/src/main/java/javax/validation/UnexpectedTypeForConstraintException.java (rev 0)
+++ validator/trunk/validation-api/src/main/java/javax/validation/UnexpectedTypeForConstraintException.java 2009-02-05 11:53:49 UTC (rev 15902)
@@ -0,0 +1,44 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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 javax.validation;
+
+import javax.validation.ValidationException;
+
+/**
+ * Exception raised in the case that the constraint validator resolution returns more than one possible validators for
+ * a given type.
+ *
+ * @author Hardy Ferentschik
+ */
+public class UnexpectedTypeForConstraintException extends ValidationException {
+ public UnexpectedTypeForConstraintException(String message) {
+ super( message );
+ }
+
+ public UnexpectedTypeForConstraintException() {
+ super();
+ }
+
+ public UnexpectedTypeForConstraintException(String message, Throwable cause) {
+ super( message, cause );
+ }
+
+ public UnexpectedTypeForConstraintException(Throwable cause) {
+ super( cause );
+ }
+}
\ No newline at end of file
Property changes on: validator/trunk/validation-api/src/main/java/javax/validation/UnexpectedTypeForConstraintException.java
___________________________________________________________________
Name: svn:keywords
+ Id
15 years, 2 months
Hibernate SVN: r15901 - in validator/trunk/hibernate-validator/src: main/java/org/hibernate/validation/engine and 4 other directories.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-02-05 06:24:23 -0500 (Thu, 05 Feb 2009)
New Revision: 15901
Added:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForString.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
Removed:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java
Modified:
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MaxValidatorForNumber.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MinValidatorForNumber.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ValidatorTypeTest.java
Log:
BVAL-90 added some more tests and made the code work with arrays
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MaxValidatorForNumber.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MaxValidatorForNumber.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MaxValidatorForNumber.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
@@ -48,12 +48,9 @@
else if ( value instanceof BigInteger ) {
return ( ( BigInteger ) value ).compareTo( BigInteger.valueOf( maxValue ) ) != 1;
}
- else if ( value instanceof Number ) {
+ else {
double doubleValue = value.doubleValue();
return doubleValue <= maxValue;
}
- else {
- return false;
- }
}
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MinValidatorForNumber.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MinValidatorForNumber.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/MinValidatorForNumber.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
@@ -48,12 +48,10 @@
else if ( value instanceof BigInteger ) {
return ( ( BigInteger ) value ).compareTo( BigInteger.valueOf( minValue ) ) != -1;
}
- else if ( value instanceof Number ) {
+ else {
double doubleValue = value.doubleValue();
return doubleValue >= minValue;
}
- else {
- return false;
- }
+
}
}
Deleted: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -1,68 +0,0 @@
-// $Id$
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2008, Red Hat Middleware LLC, and individual contributors
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* 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.hibernate.validation.constraints;
-
-import java.lang.reflect.Array;
-import java.util.Collection;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.Size;
-
-/**
- * Check that a string's length is between min and max.
- *
- * @author Emmanuel Bernard
- * @author Gavin King
- */
-//FIXME split into several type-safe validators
-public class SizeValidator implements ConstraintValidator<Size, Object> {
- private int min;
- private int max;
-
- public void initialize(Size parameters) {
- min = parameters.min();
- max = parameters.max();
- }
-
- /**
- * {@inheritDoc}
- */
- public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
- if ( value == null ) {
- return true;
- }
-
- int size;
- if ( value instanceof String ) {
- String string = ( String ) value;
- size = string.length();
-
- }
- else if ( value instanceof Collection ) {
- Collection collection = ( Collection ) value;
- size = collection.size();
- }
- else if ( value instanceof Array ) {
- size = Array.getLength( value );
- }
- else {
- throw new IllegalArgumentException( "Expected String type." );
- }
- return size >= min && size <= max;
- }
-}
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForArray.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -0,0 +1,56 @@
+// $Id: SizeValidatorForString.java 15853 2009-02-02 15:42:10Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.constraints;
+
+import java.lang.reflect.Array;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Size;
+
+/**
+ * Check that a string's length is between min and max.
+ *
+ * @author Hardy Ferentschik
+ */
+public class SizeValidatorForArray implements ConstraintValidator<Size, Object[]> {
+ private int min;
+ private int max;
+
+ public void initialize(Size parameters) {
+ min = parameters.min();
+ max = parameters.max();
+ }
+
+ /**
+ * Checks the number of entries in an array.
+ *
+ * @param array The array to validate.
+ * @param constraintValidatorContext context in which the constraint is evaluated.
+ *
+ * @return Returns <code>true</code> if the array is <code>null</code> or the number of entries in
+ * <code>array</code> is between the specified <code>min</code> and <code>max</code> values (inclusive),
+ * <code>false</code> otherwise.
+ */
+ public boolean isValid(Object[] array, ConstraintValidatorContext constraintValidatorContext) {
+ if ( array == null ) {
+ return true;
+ }
+ int length = Array.getLength( array );
+ return length >= min && length <= max;
+ }
+}
\ No newline at end of file
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForCollection.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -0,0 +1,56 @@
+// $Id: SizeValidatorForString.java 15853 2009-02-02 15:42:10Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.constraints;
+
+import java.util.Collection;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Size;
+
+/**
+ * Check that a string's length is between min and max.
+ *
+ * @author Hardy Ferentschik
+ */
+public class SizeValidatorForCollection implements ConstraintValidator<Size, Collection> {
+ private int min;
+ private int max;
+
+ public void initialize(Size parameters) {
+ min = parameters.min();
+ max = parameters.max();
+ }
+
+ /**
+ * Checks the number of entries in a map.
+ *
+ * @param collection The collection to validate.
+ * @param constraintValidatorContext context in which the constraint is evaluated.
+ *
+ * @return Returns <code>true</code> if the collection is <code>null</code> or the number of entries in
+ * <code>collection</code> is between the specified <code>min</code> and <code>max</code> values (inclusive),
+ * <code>false</code> otherwise.
+ */
+ public boolean isValid(Collection collection, ConstraintValidatorContext constraintValidatorContext) {
+ if ( collection == null ) {
+ return true;
+ }
+ int length = collection.size();
+ return length >= min && length <= max;
+ }
+}
\ No newline at end of file
Added: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForMap.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -0,0 +1,56 @@
+// $Id: SizeValidatorForString.java 15853 2009-02-02 15:42:10Z hardy.ferentschik $
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.constraints;
+
+import java.util.Map;
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Size;
+
+/**
+ * Check that a string's length is between min and max.
+ *
+ * @author Hardy Ferentschik
+ */
+public class SizeValidatorForMap implements ConstraintValidator<Size, Map> {
+ private int min;
+ private int max;
+
+ public void initialize(Size parameters) {
+ min = parameters.min();
+ max = parameters.max();
+ }
+
+ /**
+ * Checks the number of entries in a map.
+ *
+ * @param map The map to validate.
+ * @param constraintValidatorContext context in which the constraint is evaluated.
+ *
+ * @return Returns <code>true</code> if the map is <code>null</code> or the number of entries in <code>map</code>
+ * is between the specified <code>min</code> and <code>max</code> values (inclusive),
+ * <code>false</code> otherwise.
+ */
+ public boolean isValid(Map map, ConstraintValidatorContext constraintValidatorContext) {
+ if ( map == null ) {
+ return true;
+ }
+ int size = map.size();
+ return size >= min && size <= max;
+ }
+}
\ No newline at end of file
Copied: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForString.java (from rev 15883, validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidator.java)
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForString.java (rev 0)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForString.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -0,0 +1,56 @@
+// $Id$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.constraints;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorContext;
+import javax.validation.constraints.Size;
+
+/**
+ * Check that a string's length is between min and max.
+ *
+ * @author Emmanuel Bernard
+ * @author Gavin King
+ * @author Hardy Ferentschik
+ */
+public class SizeValidatorForString implements ConstraintValidator<Size, String> {
+ private int min;
+ private int max;
+
+ public void initialize(Size parameters) {
+ min = parameters.min();
+ max = parameters.max();
+ }
+
+ /**
+ * Checks the length of the specified string.
+ *
+ * @param s The string to validate.
+ * @param constraintValidatorContext context in which the constraint is evaluated.
+ *
+ * @return Returns <code>true</code> if the string is <code>null</code> or the length of <code>s</code> between the specified
+ * <code>min</code> and <code>max</code> values (inclusive), <code>false</code> otherwise.
+ */
+ public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
+ if ( s == null ) {
+ return true;
+ }
+ int length = s.length();
+ return length >= min && length <= max;
+ }
+}
Property changes on: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/constraints/SizeValidatorForString.java
___________________________________________________________________
Name: svn:keywords
+ Id
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/BuiltinConstraints.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* JBoss, Home of Professional Open Source
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
@@ -45,7 +45,10 @@
import org.hibernate.validation.constraints.NullValidator;
import org.hibernate.validation.constraints.PastValidatorForCalendar;
import org.hibernate.validation.constraints.PastValidatorForDate;
-import org.hibernate.validation.constraints.SizeValidator;
+import org.hibernate.validation.constraints.SizeValidatorForString;
+import org.hibernate.validation.constraints.SizeValidatorForCollection;
+import org.hibernate.validation.constraints.SizeValidatorForArray;
+import org.hibernate.validation.constraints.SizeValidatorForMap;
/**
* @author Hardy Ferentschik
@@ -94,7 +97,10 @@
builtinConstraints.put( Future.class, constraintList );
constraintList = new ArrayList<Class<? extends ConstraintValidator<?, ?>>>();
- constraintList.add( SizeValidator.class );
+ constraintList.add( SizeValidatorForString.class );
+ constraintList.add( SizeValidatorForCollection.class );
+ constraintList.add( SizeValidatorForArray.class );
+ constraintList.add( SizeValidatorForMap.class );
builtinConstraints.put( Size.class, constraintList );
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/engine/ConstraintTree.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -18,6 +18,7 @@
package org.hibernate.validation.engine;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -162,17 +163,13 @@
* @return The class of a matching validator.
*/
private Class findMatchingValidatorClass(Object value) {
- Class valueClass = value.getClass();
+ Class valueClass = determineValueClass( value );
+
Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes = ValidatorTypeHelper
.getValidatorsTypes( descriptor.getConstraintValidatorClasses() );
- List<Class> assignableClasses = new ArrayList<Class>();
- for ( Class clazz : validatorsTypes.keySet() ) {
- if ( clazz.isAssignableFrom( valueClass ) ) {
- assignableClasses.add( clazz );
- }
- }
+ List<Class> assignableClasses = findAssingableClasses( valueClass, validatorsTypes );
resolveAssignableClasses( assignableClasses );
if ( assignableClasses.size() != 1 ) {
@@ -191,6 +188,24 @@
return validatorsTypes.get( assignableClasses.get( 0 ) );
}
+ private List<Class> findAssingableClasses(Class valueClass, Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes) {
+ List<Class> assignableClasses = new ArrayList<Class>();
+ for ( Class clazz : validatorsTypes.keySet() ) {
+ if ( clazz.isAssignableFrom( valueClass ) ) {
+ assignableClasses.add( clazz );
+ }
+ }
+ return assignableClasses;
+ }
+
+ private Class determineValueClass(Object value) {
+ Class valueClass = value.getClass();
+ if ( valueClass.isArray() ) {
+ valueClass = Array.class;
+ }
+ return valueClass;
+ }
+
/**
* Tries to reduce all assignable classes down to a single class.
*
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ReflectionHelper.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -152,9 +152,15 @@
}
}
}
- catch ( Exception e ) {
+ catch ( NoSuchMethodException nsme ) {
// ignore
}
+ catch ( IllegalAccessException iae ) {
+ // ignore
+ }
+ catch ( InvocationTargetException ite ) {
+ // ignore
+ }
return isMultiValueConstraint;
}
@@ -181,9 +187,15 @@
}
}
}
- catch ( Exception e ) {
+ catch ( NoSuchMethodException nsme ) {
// ignore
}
+ catch ( IllegalAccessException iae ) {
+ // ignore
+ }
+ catch ( InvocationTargetException ite ) {
+ // ignore
+ }
return annotationList;
}
Modified: validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java
===================================================================
--- validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/main/java/org/hibernate/validation/util/ValidatorTypeHelper.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -18,6 +18,8 @@
package org.hibernate.validation.util;
import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
@@ -59,36 +61,23 @@
}
private static Class<?> extractType(Class<? extends ConstraintValidator<?, ?>> validator) {
-
Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
Type constraintValidatorType = resolveTypes( resolvedTypes, validator );
//we now have all bind from a type to its resolution at one level
-
- //FIXME throw assertion exception if constraintValidatorType == null
Type validatorType = ( ( ParameterizedType ) constraintValidatorType ).getActualTypeArguments()[VALIDATOR_TYPE_INDEX];
- while ( resolvedTypes.containsKey( validatorType ) ) {
- validatorType = resolvedTypes.get( validatorType );
+ if ( validatorType == null ) {
+ throw new ValidationException( "Null is an invalid type for a constraint validator." );
}
- //FIXME raise an exception if validatorType is not a class
- return ( Class<?> ) validatorType;
- }
+ else if ( validatorType instanceof GenericArrayType ) {
+ validatorType = Array.class;
+ }
- //TEst method, remove
- public static Type extractTypeLoose(Class<? extends ConstraintValidator<?, ?>> validator) {
-
- Map<Type, Type> resolvedTypes = new HashMap<Type, Type>();
- Type constraintValidatorType = resolveTypes( resolvedTypes, validator );
-
- //we now have all bind from a type to its resolution at one level
-
- //FIXME throw assertion exception if constraintValidatorType == null
- Type validatorType = ( ( ParameterizedType ) constraintValidatorType ).getActualTypeArguments()[VALIDATOR_TYPE_INDEX];
while ( resolvedTypes.containsKey( validatorType ) ) {
validatorType = resolvedTypes.get( validatorType );
}
//FIXME raise an exception if validatorType is not a class
- return validatorType;
+ return ( Class<?> ) validatorType;
}
private static Type resolveTypes(Map<Type, Type> resolvedTypes, Type type) {
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ConstraintCompositionTest.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -24,10 +24,6 @@
import static org.junit.Assert.fail;
import org.junit.Test;
-import org.hibernate.validation.constraints.NotNullValidator;
-import org.hibernate.validation.constraints.PatternValidator;
-import org.hibernate.validation.constraints.SizeValidator;
-import org.hibernate.validation.constraints.composition.GermanZipcodeConstraintValidator;
import org.hibernate.validation.eg.FrenchAddress;
import org.hibernate.validation.eg.GermanAddress;
import static org.hibernate.validation.util.TestUtil.assertConstraintViolation;
@@ -54,7 +50,6 @@
assertConstraintViolation(
constraintViolations.iterator().next(),
"may not be null",
- NotNullValidator.class,
FrenchAddress.class,
null,
"zipCode"
@@ -69,7 +64,6 @@
assertConstraintViolation(
violation,
"A french zip code has a length of 5",
- SizeValidator.class,
FrenchAddress.class,
"abc",
"zipCode"
@@ -79,7 +73,6 @@
assertConstraintViolation(
violation,
"must match \"d*\"",
- PatternValidator.class,
FrenchAddress.class,
"abc",
"zipCode"
@@ -89,7 +82,6 @@
assertConstraintViolation(
violation,
"must match \".....\"",
- PatternValidator.class,
FrenchAddress.class,
"abc",
"zipCode"
@@ -109,7 +101,6 @@
assertConstraintViolation(
violation,
"A french zip code has a length of 5",
- SizeValidator.class,
FrenchAddress.class,
"123",
"zipCode"
@@ -119,7 +110,6 @@
assertConstraintViolation(
violation,
"must match \".....\"",
- PatternValidator.class,
FrenchAddress.class,
"123",
"zipCode"
@@ -148,7 +138,6 @@
assertConstraintViolation(
constraintViolations.iterator().next(),
"Falsche Postnummer.",
- GermanZipcodeConstraintValidator.class,
GermanAddress.class,
null,
"zipCode"
@@ -170,7 +159,6 @@
assertConstraintViolation(
constraintViolations.iterator().next(),
"Falsche Postnummer.",
- GermanZipcodeConstraintValidator.class,
GermanAddress.class,
"abc",
"zipCode"
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Coordinate.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -0,0 +1,32 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine.validatorresolution;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Coordinate {
+
+ long longitude;
+ long latidute;
+
+ public Coordinate(long longitude, long latidute) {
+ this.longitude = longitude;
+ this.latidute = latidute;
+ }
+}
Added: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java (rev 0)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/Suburb.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -0,0 +1,83 @@
+// $Id:$
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2008, Red Hat Middleware LLC, and individual contributors
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* 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.hibernate.validation.engine.validatorresolution;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.validation.constraints.Size;
+
+/**
+ * @author Hardy Ferentschik
+ */
+public class Suburb {
+ public enum Facility {
+ SHOPPING_MALL, BUS_TERMINAL
+ }
+
+ @Size(min = 5, max = 10)
+ private String name;
+
+ @Size(min = 2, max = 2)
+ private Map<Facility, Boolean> facilities;
+
+ @Size(min = 2)
+ private Set<String> streetNames;
+
+ @Size(min = 4, max = 1000)
+ private Coordinate[] boundingBox;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Map<Facility, Boolean> getFacilities() {
+ return facilities;
+ }
+
+ public void addFacility(Facility f, Boolean exist) {
+ if ( facilities == null ) {
+ facilities = new HashMap<Facility, Boolean>();
+ }
+ facilities.put( f, exist );
+ }
+
+ public Set<String> getStreetNames() {
+ return streetNames;
+ }
+
+ public void addStreetName(String streetName) {
+ if ( streetNames == null ) {
+ streetNames = new HashSet<String>();
+ }
+ streetNames.add( streetName );
+ }
+
+ public Coordinate[] getBoundingBox() {
+ return boundingBox;
+ }
+
+ public void setBoundingBox(Coordinate[] boundingBox) {
+ this.boundingBox = boundingBox;
+ }
+}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/validatorresolution/ValidatorResolutionTest.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -27,6 +27,7 @@
import org.junit.Test;
import org.hibernate.validation.eg.MultipleMinMax;
+import static org.hibernate.validation.util.TestUtil.assertConstraintViolation;
import static org.hibernate.validation.util.TestUtil.assertNumberOfViolations;
import static org.hibernate.validation.util.TestUtil.getValidator;
@@ -59,4 +60,80 @@
assertTrue( e.getMessage().startsWith( "There are multiple validators" ) );
}
}
+
+ @Test
+ public void testMultipleSizeValidators() {
+ Validator validator = getValidator();
+
+ Suburb suburb = new Suburb();
+
+ // all values are null and should pass
+ Set<ConstraintViolation<Suburb>> constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 0 );
+
+ suburb.setName( "" );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 1 );
+ assertConstraintViolation(
+ constraintViolations.iterator().next(), "size must be between 5 and 10", Suburb.class, "", "name"
+ );
+
+ suburb.setName( "Hoegsbo" );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 0 );
+
+ suburb.addFacility( Suburb.Facility.SHOPPING_MALL, false );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 1 );
+ assertConstraintViolation(
+ constraintViolations.iterator().next(),
+ "size must be between 2 and 2",
+ Suburb.class,
+ suburb.getFacilities(),
+ "facilities"
+ );
+
+ suburb.addFacility( Suburb.Facility.BUS_TERMINAL, true );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 0 );
+
+ suburb.addStreetName( "Sikelsgatan" );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 1 );
+ assertConstraintViolation(
+ constraintViolations.iterator().next(),
+ "size must be between 2 and 2147483647",
+ Suburb.class,
+ suburb.getStreetNames(),
+ "streetNames"
+ );
+
+ suburb.addStreetName( "Marklandsgatan" );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 0 );
+
+ Coordinate[] boundingBox = new Coordinate[3];
+ boundingBox[0] = new Coordinate( 0l, 0l );
+ boundingBox[1] = new Coordinate( 0l, 1l );
+ boundingBox[2] = new Coordinate( 1l, 0l );
+ suburb.setBoundingBox( boundingBox );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 1 );
+ assertConstraintViolation(
+ constraintViolations.iterator().next(),
+ "size must be between 4 and 1000",
+ Suburb.class,
+ suburb.getBoundingBox(),
+ "boundingBox"
+ );
+
+ boundingBox = new Coordinate[4];
+ boundingBox[0] = new Coordinate( 0l, 0l );
+ boundingBox[1] = new Coordinate( 0l, 1l );
+ boundingBox[2] = new Coordinate( 1l, 0l );
+ boundingBox[3] = new Coordinate( 1l, 1l );
+ suburb.setBoundingBox( boundingBox );
+ constraintViolations = validator.validate( suburb );
+ assertNumberOfViolations( constraintViolations, 0 );
+ }
}
\ No newline at end of file
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/TestUtil.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -48,48 +48,39 @@
return hibernateValidator;
}
- public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean, Object invalidValue, String propertyPath, Class leafBean) {
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean, Object invalidValue, String propertyPath, Class leafBean) {
assertEquals(
"Wrong leaf bean type",
leafBean,
violation.getLeafBean().getClass()
);
- assertConstraintViolation( violation, errorMessage, constraintType, rootBean, invalidValue, propertyPath );
+ assertConstraintViolation( violation, errorMessage, rootBean, invalidValue, propertyPath );
}
- public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean, Object invalidValue, String propertyPath) {
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean, Object invalidValue, String propertyPath) {
assertEquals(
"Wrong propertyPath",
propertyPath,
violation.getPropertyPath()
);
- assertConstraintViolation( violation, errorMessage, constraintType, rootBean, invalidValue );
+ assertConstraintViolation( violation, errorMessage, rootBean, invalidValue );
}
- public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean, Object invalidValue) {
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean, Object invalidValue) {
assertEquals(
"Wrong invalid value",
invalidValue,
violation.getInvalidValue()
);
- assertConstraintViolation( violation, errorMessage, constraintType, rootBean );
+ assertConstraintViolation( violation, errorMessage, rootBean );
}
- public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType, Class rootBean) {
+ public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class rootBean) {
assertEquals(
"Wrong root bean type",
rootBean,
violation.getRootBean().getClass()
);
- assertConstraintViolation( violation, errorMessage, constraintType );
- }
-
- public static void assertConstraintViolation(ConstraintViolation violation, String errorMessage, Class constraintType) {
- assertEquals(
- "Wrong constraint error Type",
- constraintType,
- violation.getConstraintDescriptor().getConstraintValidatorClasses().get(0)
- );
assertConstraintViolation( violation, errorMessage );
}
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ValidatorTypeTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ValidatorTypeTest.java 2009-02-05 08:27:17 UTC (rev 15900)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/util/ValidatorTypeTest.java 2009-02-05 11:24:23 UTC (rev 15901)
@@ -18,14 +18,10 @@
package org.hibernate.validation.util;
import java.lang.annotation.Annotation;
-import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorContext;
-import javax.validation.constraints.NotNull;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
@@ -46,32 +42,5 @@
Map<Class<?>, Class<? extends ConstraintValidator<? extends Annotation, ?>>> validatorsTypes = ValidatorTypeHelper
.getValidatorsTypes( validators );
assertEquals( FrenchZipcodeConstraintValidator.class, validatorsTypes.get( String.class ) );
-
- Type type = ValidatorTypeHelper
- .extractTypeLoose( TestValidator.class );
-
-
- Type type2 = ValidatorTypeHelper
- .extractTypeLoose( TestValidator2.class );
- assertEquals( type, type2 );
-
}
-
- public static class TestValidator implements ConstraintValidator<NotNull, Set<String>> {
- public void initialize(NotNull constraintAnnotation) {
- }
-
- public boolean isValid(Set<String> object, ConstraintValidatorContext constraintValidatorContext) {
- return false;
- }
- }
-
- public static class TestValidator2 implements ConstraintValidator<NotNull, Set<String>> {
- public void initialize(NotNull constraintAnnotation) {
- }
-
- public boolean isValid(Set<String> object, ConstraintValidatorContext constraintValidatorContext) {
- return true;
- }
- }
}
\ No newline at end of file
15 years, 2 months
Hibernate SVN: r15900 - in core/branches/envers-hibernate-3.3/src: main/java/org/hibernate/envers/configuration/metadata/reader and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-02-05 03:27:17 -0500 (Thu, 05 Feb 2009)
New Revision: 15900
Added:
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverride.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverrides.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java
core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java
Modified:
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java
Log:
svn merge -r 15867:15899 https://svn.jboss.org/repos/hibernate/core/trunk/envers .
Copied: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverride.java (from rev 15899, core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverride.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverride.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverride.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,41 @@
+package org.hibernate.envers;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * The {@code AuditingOverride} annotation is used to override the auditing
+ * behavior of a field (or property) inside an embedded component.
+ *
+ * @author Erik-Berndt Scheper
+ * @see javax.persistence.Embedded
+ * @see javax.persistence.Embeddable
+ * @see javax.persistence.MappedSuperclass
+ * @see javax.persistence.AssociationOverride
+ * @see AuditJoinTable
+ */
+@Target({ TYPE, METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface AuditOverride {
+
+ /**
+ * @return <strong>Required</strong> Name of the field (or property) whose mapping
+ * is being overridden.
+ */
+ String name();
+
+ /**
+ * @return Indicates if the field (or property) is audited; defaults to {@code true}.
+ */
+ boolean isAudited() default true;
+
+ /**
+ * @return New {@link AuditJoinTable} used for this field (or property). Its value
+ * is ignored if {@link #isAudited()} equals to {@code false}.
+ */
+ AuditJoinTable auditJoinTable() default @AuditJoinTable;
+}
Copied: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverrides.java (from rev 15899, core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverrides.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverrides.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/AuditOverrides.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,32 @@
+package org.hibernate.envers;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * The {@code AuditingOverrides} annotation is used to override the auditing
+ * behavior for one ore more fields (or properties) inside an embedded
+ * component.
+ *
+ * @author Erik-Berndt Scheper
+ * @see javax.persistence.Embedded
+ * @see javax.persistence.Embeddable
+ * @see javax.persistence.MappedSuperclass
+ * @see javax.persistence.AssociationOverride
+ * @see javax.persistence.AssociationOverrides
+ * @see AuditJoinTable
+ * @see AuditOverride
+ */
+@Target({ TYPE, METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface AuditOverrides {
+ /**
+ * @return An array of {@link AuditOverride} values, to define the new auditing
+ * behavior.
+ */
+ AuditOverride[] value();
+}
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-02-05 08:22:40 UTC (rev 15899)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -1,26 +1,31 @@
package org.hibernate.envers.configuration.metadata.reader;
+import static org.hibernate.envers.tools.Tools.newHashSet;
+
+import java.lang.annotation.Annotation;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.JoinColumn;
+import javax.persistence.MapKey;
+import javax.persistence.Version;
+
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.envers.AuditJoinTable;
+import org.hibernate.envers.AuditOverride;
+import org.hibernate.envers.AuditOverrides;
+import org.hibernate.envers.Audited;
import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.NotAudited;
-import org.hibernate.envers.Audited;
-import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.configuration.GlobalConfiguration;
-import static org.hibernate.envers.tools.Tools.*;
import org.hibernate.envers.tools.MappingTools;
+import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Component;
import org.hibernate.mapping.Value;
-import org.hibernate.annotations.common.reflection.XProperty;
-import org.hibernate.annotations.common.reflection.XClass;
import org.jboss.envers.Versioned;
-import javax.persistence.Version;
-import javax.persistence.MapKey;
-import javax.persistence.JoinColumn;
-import java.util.Iterator;
-import java.util.Set;
-import java.lang.annotation.Annotation;
-
/**
* Reads persistent properties form a
* {@link org.hibernate.envers.configuration.metadata.reader.PersistentPropertiesSource}
@@ -28,6 +33,7 @@
* {@link org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesHolder},
* filling all the auditing data.
* @author Adam Warski (adam at warski dot org)
+ * @author Erik-Berndt Scheper
*/
public class AuditedPropertiesReader {
private final ModificationStore defaultStore;
@@ -97,7 +103,6 @@
ComponentAuditingData componentData = new ComponentAuditingData();
isAudited = fillPropertyData(property, componentData, accessType);
- // TODO: component stuff
PersistentPropertiesSource componentPropertiesSource = new ComponentPropertiesSource(
property.getType(), (Component) propertyValue);
new AuditedPropertiesReader(ModificationStore.FULL, componentPropertiesSource, componentData,
@@ -164,6 +169,10 @@
propertyData.setAccessType(accessType);
addPropertyJoinTables(property, propertyData);
+ addPropertyAuditingOverrides(property, propertyData);
+ if (!processPropertyAuditingOverrides(property, propertyData)) {
+ return false; // not audited due to AuditOverride annotation
+ }
addPropertyMapKey(property, propertyData);
return true;
@@ -177,6 +186,7 @@
}
private void addPropertyJoinTables(XProperty property, PropertyAuditingData propertyData) {
+ // first set the join table based on the AuditJoinTable annotation
AuditJoinTable joinTable = property.getAnnotation(AuditJoinTable.class);
if (joinTable != null) {
propertyData.setJoinTable(joinTable);
@@ -185,6 +195,54 @@
}
}
+ /***
+ * Add the {@link org.hibernate.envers.AuditOverride} annotations.
+ *
+ * @param property the property being processed
+ * @param propertyData the Envers auditing data for this property
+ */
+ private void addPropertyAuditingOverrides(XProperty property, PropertyAuditingData propertyData) {
+ AuditOverride annotationOverride = property.getAnnotation(AuditOverride.class);
+ if (annotationOverride != null) {
+ propertyData.addAuditingOverride(annotationOverride);
+ }
+ AuditOverrides annotationOverrides = property.getAnnotation(AuditOverrides.class);
+ if (annotationOverrides != null) {
+ propertyData.addAuditingOverrides(annotationOverrides);
+ }
+ }
+
+ /**
+ * Process the {@link org.hibernate.envers.AuditOverride} annotations for this property.
+ *
+ * @param property
+ * the property for which the {@link org.hibernate.envers.AuditOverride}
+ * annotations are being processed
+ * @param propertyData
+ * the Envers auditing data for this property
+ * @return {@code false} if isAudited() of the override annotation was set to
+ */
+ private boolean processPropertyAuditingOverrides(XProperty property, PropertyAuditingData propertyData) {
+ // if this property is part of a component, process all override annotations
+ if (this.auditedPropertiesHolder instanceof ComponentAuditingData) {
+ List<AuditOverride> overrides = ((ComponentAuditingData) this.auditedPropertiesHolder).getAuditingOverrides();
+ for (AuditOverride override : overrides) {
+ if (property.getName().equals(override.name())) {
+ // the override applies to this property
+ if (!override.isAudited()) {
+ return false;
+ } else {
+ if (override.auditJoinTable() != null) {
+ propertyData.setJoinTable(override.auditJoinTable());
+ }
+ }
+ }
+ }
+
+ }
+ return true;
+ }
+
private static AuditJoinTable DEFAULT_AUDIT_JOIN_TABLE = new AuditJoinTable() {
public String name() { return ""; }
public String schema() { return ""; }
Modified: core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java
===================================================================
--- core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java 2009-02-05 08:22:40 UTC (rev 15899)
+++ core/branches/envers-hibernate-3.3/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -24,6 +24,11 @@
*/
package org.hibernate.envers.configuration.metadata.reader;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.hibernate.envers.AuditOverride;
+import org.hibernate.envers.AuditOverrides;
import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.entities.PropertyData;
@@ -38,6 +43,7 @@
private String mapKey;
private AuditJoinTable joinTable;
private String accessType;
+ private final List<AuditOverride> auditJoinTableOverrides = new ArrayList<AuditOverride>(0);
public PropertyAuditingData() {
}
@@ -100,4 +106,33 @@
public PropertyData getPropertyData() {
return new PropertyData(name, beanName, accessType, store);
}
+
+ public List<AuditOverride> getAuditingOverrides() {
+ return auditJoinTableOverrides;
+ }
+
+ public void addAuditingOverride(AuditOverride annotation) {
+ if (annotation != null) {
+ String overrideName = annotation.name();
+ boolean present = false;
+ for (AuditOverride current : auditJoinTableOverrides) {
+ if (current.name().equals(overrideName)) {
+ present = true;
+ break;
+ }
+ }
+ if (!present) {
+ auditJoinTableOverrides.add(annotation);
+ }
+ }
+ }
+
+ public void addAuditingOverrides(AuditOverrides annotationOverrides) {
+ if (annotationOverrides != null) {
+ for (AuditOverride annotation : annotationOverrides.value()) {
+ addAuditingOverride(annotation);
+ }
+ }
+ }
+
}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java (from rev 15899, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,81 @@
+package org.hibernate.envers.test.integration.naming;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Embeddable;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+
+import org.hibernate.annotations.FetchMode;
+
+/**
+ * An embeddable component containing a list of
+ * {@link VersionsJoinTableRangeTestEntitySuperClass}-instances
+ *
+ * @author Erik-Berndt Scheper
+ * @param <T>
+ */
+@Embeddable
+public final class VersionsJoinTableRangeComponent<T extends VersionsJoinTableRangeTestEntitySuperClass> {
+
+ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+ @org.hibernate.annotations.Fetch(value = FetchMode.SUBSELECT)
+ @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
+ @JoinColumn(name = "VJTRCTE_ID", insertable = true, updatable = false, nullable = false)
+// Note: If this is processed without override annotation, then we should get a
+// org.hibernate.DuplicateMappingException:
+// Duplicate class/entity mapping JOIN_TABLE_COMPONENT_1_AUD
+ @org.hibernate.envers.AuditJoinTable(name = "JOIN_TABLE_COMPONENT_1_AUD", inverseJoinColumns = @JoinColumn(name = "VJTRTE_ID"))
+ private List<T> range = new ArrayList<T>();
+
+ // ********************** Accessor Methods ********************** //
+
+ protected List<T> getRange() {
+ return this.range;
+ }
+
+ // ********************** Common Methods ********************** //
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((range == null) ? 0 : range.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeComponent<?> other = (VersionsJoinTableRangeComponent<?>) obj;
+ if (range == null) {
+ if (other.range != null)
+ return false;
+ } else if (!range.equals(other.range))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponent {");
+ output.append(" range = \"");
+ for (T instance : range) {
+ output.append(instance).append("\n");
+ }
+ output.append("\"}");
+
+ return output.toString();
+ }
+
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java (from rev 15899, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,295 @@
+/*
+ * 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.envers.test.integration.naming;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.components.Component1;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.PersistentClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Test class for {@link VersionsJoinTableRangeComponentTestEntity}, to test
+ * various {@link org.hibernate.envers.AuditOverride} annotations.
+ *
+ * @author Erik-Berndt Scheper
+ */
+public class VersionsJoinTableRangeComponentNamingTest extends
+ AbstractEntityTest {
+ private Integer vjrcte_id;
+ private Integer vjtrte_id;
+ private Integer vjtrtae_id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(VersionsJoinTableRangeComponentTestEntity.class);
+ cfg.addAnnotatedClass(VersionsJoinTableRangeTestEntitySuperClass.class);
+ cfg.addAnnotatedClass(VersionsJoinTableRangeTestEntity.class);
+ cfg.addAnnotatedClass(VersionsJoinTableRangeTestAlternateEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ // create an instance of the test entity
+ VersionsJoinTableRangeComponentTestEntity vjrcte = new VersionsJoinTableRangeComponentTestEntity();
+ em.persist(vjrcte);
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+
+ vjrcte = em.find(VersionsJoinTableRangeComponentTestEntity.class,
+ vjrcte.getId());
+
+ // create a component containing a list of
+ // VersionsJoinTableRangeTestEntity-instances
+ VersionsJoinTableRangeTestEntity vjtrte = new VersionsJoinTableRangeTestEntity();
+ vjtrte.setGenericValue("generic1");
+ vjtrte.setValue("value1");
+ // and add it to the test entity
+ vjrcte.getComponent1().getRange().add(vjtrte);
+
+ // create a second component containing a list of
+ // VersionsJoinTableRangeTestAlternateEntity-instances
+ VersionsJoinTableRangeTestAlternateEntity vjtrtae1 = new VersionsJoinTableRangeTestAlternateEntity();
+ vjtrtae1.setGenericValue("generic2");
+ vjtrtae1.setAlternateValue("alternateValue2");
+ // and add it to the test entity
+ vjrcte.getComponent2().getRange().add(vjtrtae1);
+
+ // create a third component, and add it to the test entity
+ Component1 simpleComponent = new Component1("string1", "string2");
+ vjrcte.setComponent3(simpleComponent);
+
+ em.persist(vjtrte);
+ em.persist(vjtrtae1);
+ em.persist(vjrcte);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+
+ vjrcte = em.find(VersionsJoinTableRangeComponentTestEntity.class,
+ vjrcte.getId());
+ vjtrte = em
+ .find(VersionsJoinTableRangeTestEntity.class, vjtrte.getId());
+ vjtrtae1 = em.find(VersionsJoinTableRangeTestAlternateEntity.class,
+ vjtrtae1.getId());
+
+ assert vjrcte != null;
+ assert vjtrte != null;
+ assert vjtrtae1 != null;
+
+ List<VersionsJoinTableRangeTestEntity> ent1List = vjrcte
+ .getComponent1().getRange();
+ assert ent1List.size() == 1;
+ assert vjtrte.equals(ent1List.get(0));
+
+ List<VersionsJoinTableRangeTestAlternateEntity> ent2List = vjrcte
+ .getComponent2().getRange();
+ assert ent2List.size() == 1;
+ assert vjtrtae1.equals(ent2List.get(0));
+
+ em.getTransaction().commit();
+
+ vjrcte_id = vjrcte.getId();
+ vjtrte_id = vjtrte.getId();
+ vjtrtae_id1 = vjtrtae1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2).equals(
+ getAuditReader().getRevisions(
+ VersionsJoinTableRangeComponentTestEntity.class,
+ vjrcte_id));
+ assert Arrays.asList(2).equals(
+ getAuditReader().getRevisions(
+ VersionsJoinTableRangeTestEntity.class, vjtrte_id));
+ assert Arrays.asList(2).equals(
+ getAuditReader().getRevisions(
+ VersionsJoinTableRangeTestAlternateEntity.class,
+ vjtrtae_id1));
+ }
+
+ @Test
+ public void testHistoryOfUniId1() {
+ VersionsJoinTableRangeTestEntity vjtrte = getEntityManager().find(
+ VersionsJoinTableRangeTestEntity.class, vjtrte_id);
+ VersionsJoinTableRangeTestAlternateEntity vjtrtae = getEntityManager()
+ .find(VersionsJoinTableRangeTestAlternateEntity.class,
+ vjtrtae_id1);
+
+ VersionsJoinTableRangeComponentTestEntity rev1 = getAuditReader().find(
+ VersionsJoinTableRangeComponentTestEntity.class, vjrcte_id, 1);
+ VersionsJoinTableRangeComponentTestEntity rev2 = getAuditReader().find(
+ VersionsJoinTableRangeComponentTestEntity.class, vjrcte_id, 2);
+
+ assert rev1.getComponent1().getRange().size() == 0;
+ assert rev1.getComponent2().getRange().size() == 0;
+
+ assert rev2.getComponent1().getRange().size() == 1;
+ assert rev2.getComponent1().getRange().get(0).equals(vjtrte);
+ assert rev2.getComponent2().getRange().size() == 1;
+ assert rev2.getComponent2().getRange().get(0).equals(vjtrtae);
+ }
+
+ /* The Audit join tables we expect */
+ private final static String COMPONENT_1_AUDIT_JOIN_TABLE_NAME = "JOIN_TABLE_COMPONENT_1_AUD";
+ private final static String COMPONENT_2_AUDIT_JOIN_TABLE_NAME = "JOIN_TABLE_COMPONENT_2_AUD";
+
+ /* The Audit join tables that should NOT be there */
+ private final static String UNMODIFIED_COMPONENT_1_AUDIT_JOIN_TABLE_NAME = "VersionsJoinTableRangeComponentTestEntity_VersionsJoinTableRangeTestEntity_AUD";
+ private final static String UNMODIFIED_COMPONENT_2_AUDIT_JOIN_TABLE_NAME = "VersionsJoinTableRangeComponentTestEntity_VersionsJoinTableRangeTestAlternateEntity_AUD";
+
+ @Test
+ public void testExpectedTableNameComponent1() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_1_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+ assert COMPONENT_1_AUDIT_JOIN_TABLE_NAME.equals(auditClass.getTable()
+ .getName());
+ }
+
+ @Test
+ public void testExpectedTableNameComponent2() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_2_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+ assert COMPONENT_2_AUDIT_JOIN_TABLE_NAME.equals(auditClass.getTable()
+ .getName());
+ }
+
+ @Test
+ public void testWrongTableNameComponent1() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ UNMODIFIED_COMPONENT_1_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass == null;
+ }
+
+ @Test
+ public void testWrongTableNameComponent2() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ UNMODIFIED_COMPONENT_2_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass == null;
+ }
+
+ @Test
+ public void testJoinColumnNamesComponent1() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_1_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+
+ @SuppressWarnings( { "unchecked" })
+ Iterator<Column> columns = auditClass.getTable().getColumnIterator();
+
+ boolean id1Found = false;
+ boolean id2Found = false;
+
+ while (columns.hasNext()) {
+ Column column = columns.next();
+ if ("VJTRCTE1_ID".equals(column.getName())) {
+ id1Found = true;
+ }
+
+ if ("VJTRTE_ID".equals(column.getName())) {
+ id2Found = true;
+ }
+ }
+
+ assert id1Found && id2Found;
+ }
+
+ @Test
+ public void testJoinColumnNamesComponent2() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_2_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+
+ @SuppressWarnings( { "unchecked" })
+ Iterator<Column> columns = auditClass.getTable().getColumnIterator();
+
+ boolean id1Found = false;
+ boolean id2Found = false;
+
+ while (columns.hasNext()) {
+ Column column = columns.next();
+ if ("VJTRCTE2_ID".equals(column.getName())) {
+ id1Found = true;
+ }
+
+ if ("VJTRTAE_ID".equals(column.getName())) {
+ id2Found = true;
+ }
+ }
+
+ assert id1Found && id2Found;
+ }
+
+ /**
+ * Verify that
+ * {@link VersionsJoinTableRangeComponentTestEntity#getComponent3()} is
+ * partially audited.
+ */
+ @Test
+ public void testOverrideNotAudited() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ VersionsJoinTableRangeComponentTestEntity.class.getName()
+ + "_AUD");
+ assert auditClass != null;
+
+ @SuppressWarnings( { "unchecked" })
+ Iterator<Column> columns = auditClass.getTable().getColumnIterator();
+
+ boolean auditColumn1Found = false;
+ boolean auditColumn2Found = false;
+
+ while (columns.hasNext()) {
+ Column column = columns.next();
+ if ("STR1".equals(column.getName())) {
+ auditColumn1Found = true;
+ }
+
+ if ("STR2".equals(column.getName())) {
+ auditColumn2Found = true;
+ }
+ }
+
+ assert auditColumn1Found && !auditColumn2Found;
+ }
+
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java (from rev 15899, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,190 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.AssociationOverride;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Table;
+
+import org.hibernate.envers.test.entities.components.Component1;
+import org.hibernate.envers.AuditOverride;
+import org.hibernate.envers.AuditOverrides;
+
+/**
+ * Test entity, containing two embedded components, which each contain a list of
+ * {@link VersionsJoinTableRangeTestEntitySuperClass}-instances
+ *
+ * @author Erik-Berndt Scheper
+ */
+@Entity
+@Table(name = "COMPONENT_TEST_ENTITY")
+public class VersionsJoinTableRangeComponentTestEntity {
+ @Id
+ @GeneratedValue
+ @Column(name = "ID")
+ private Integer id;
+
+ /**
+ * An embedded component, containing a list of
+ * {@link VersionsJoinTableRangeTestEntity}-instances.
+ */
+ @Embedded
+ @AssociationOverride(name = "range", joinColumns = { @JoinColumn(name = "VJTRCTE1_ID", insertable = true, updatable = false, nullable = false) })
+ @org.hibernate.envers.Audited
+ @AuditOverride(name = "range", auditJoinTable = @org.hibernate.envers.AuditJoinTable(name = "JOIN_TABLE_COMPONENT_1_AUD", inverseJoinColumns = @JoinColumn(name = "VJTRTE_ID")))
+ private VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity> component1 = new VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity>();
+
+ /**
+ * An embedded component, containing a list of
+ * {@link VersionsJoinTableRangeTestAlternateEntity}-instances.
+ */
+ @Embedded
+ @AssociationOverride(name = "range", joinColumns = { @JoinColumn(name = "VJTRCTE2_ID", insertable = true, updatable = false, nullable = false) })
+ @org.hibernate.envers.Audited
+ @AuditOverrides(value = { @AuditOverride(name = "range", auditJoinTable = @org.hibernate.envers.AuditJoinTable(name = "JOIN_TABLE_COMPONENT_2_AUD", inverseJoinColumns = @JoinColumn(name = "VJTRTAE_ID"))) })
+ private VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity> component2 = new VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity>();
+
+ /**
+ * An embedded component, containing a list of NOT AUDITED
+ * {@link VersionsJoinTableRangeTestAlternateEntity}-instances.
+ */
+ @Embedded
+ @AttributeOverrides(value={@AttributeOverride(name="str1", column=@Column(name="STR1")), @AttributeOverride(name="str2", column=@Column(name="STR2"))})
+ @org.hibernate.envers.Audited
+ @AuditOverrides(value={@AuditOverride(name="str2", isAudited = false)})
+ private Component1 component3;
+
+ /**
+ * Default constructor
+ */
+ public VersionsJoinTableRangeComponentTestEntity() {
+ super();
+ }
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ protected void setId(Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the component1
+ */
+ public VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity> getComponent1() {
+ return component1;
+ }
+
+ /**
+ * @param component1
+ * the component1 to set
+ */
+ public void setComponent1(
+ VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity> component1) {
+ this.component1 = component1;
+ }
+
+ /**
+ * @return the component2
+ */
+ public VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity> getComponent2() {
+ return component2;
+ }
+
+ /**
+ * @param component2
+ * the component2 to set
+ */
+ public void setComponent2(
+ VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity> component2) {
+ this.component2 = component2;
+ }
+
+ /**
+ * @return the component3
+ */
+ public Component1 getComponent3() {
+ return component3;
+ }
+
+ /**
+ * @param component3
+ * the component3 to set
+ */
+ public void setComponent3(Component1 component3) {
+ this.component3 = component3;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((component1 == null) ? 0 : component1.hashCode());
+ result = prime * result
+ + ((component2 == null) ? 0 : component2.hashCode());
+ result = prime * result
+ + ((component3 == null) ? 0 : component3.hashCode());
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeComponentTestEntity other = (VersionsJoinTableRangeComponentTestEntity) obj;
+ if (component1 == null) {
+ if (other.component1 != null)
+ return false;
+ } else if (!component1.equals(other.component1))
+ return false;
+ if (component2 == null) {
+ if (other.component2 != null)
+ return false;
+ } else if (!component2.equals(other.component2))
+ return false;
+ if (component3 == null) {
+ if (other.component3 != null)
+ return false;
+ } else if (!component3.equals(other.component3))
+ return false;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponentTestEntity {");
+ output.append(" id = \"").append(this.getId()).append("\",");
+ output.append(" component1 = \"").append(this.component1)
+ .append("\", ");
+ output.append(" component2 = \"").append(this.component2).append("\"}");
+ output.append(" component3 = \"").append(this.component3).append("\"}");
+ return output.toString();
+ }
+
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java (from rev 15899, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,82 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * Alternate implementation of mapped superclass for Audit join table test.
+ *
+ * @author Erik-Berndt Scheper
+ * @see VersionsJoinTableRangeTestEntity
+ * @see VersionsJoinTableRangeTestEntitySuperClass
+ */
+@Entity
+@Table(name = "RANGE_TEST_ALTERNATE_ENTITY")
+(a)org.hibernate.envers.Audited
+public class VersionsJoinTableRangeTestAlternateEntity extends
+ VersionsJoinTableRangeTestEntitySuperClass {
+
+ private String alternateValue;
+
+ /**
+ * Default constructor
+ */
+ public VersionsJoinTableRangeTestAlternateEntity() {
+ super();
+ }
+
+ /**
+ * @return the alternateValue
+ */
+ public String getAlternateValue() {
+ return alternateValue;
+ }
+
+ /**
+ * @param alternateValue
+ * the alternateValue to set
+ */
+ public void setAlternateValue(String alternateValue) {
+ this.alternateValue = alternateValue;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result
+ + ((alternateValue == null) ? 0 : alternateValue.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeTestAlternateEntity other = (VersionsJoinTableRangeTestAlternateEntity) obj;
+ if (alternateValue == null) {
+ if (other.alternateValue != null)
+ return false;
+ } else if (!alternateValue.equals(other.alternateValue))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponentTestEntity {");
+ output.append(" id = \"").append(getId()).append("\", ");
+ output.append(" genericValue = \"").append(getGenericValue()).append(
+ "\", ");
+ output.append(" alternateValue = \"").append(this.alternateValue)
+ .append("\"}");
+ return output.toString();
+ }
+
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java (from rev 15899, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,80 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * Concrete implementation of mapped superclass for Audit join table test.
+ *
+ * @author Erik-Berndt Scheper
+ * @see VersionsJoinTableRangeTestAlternateEntity
+ * @see VersionsJoinTableRangeTestEntitySuperClass
+ */
+@Entity
+@Table(name = "RANGE_TEST_ENTITY")
+(a)org.hibernate.envers.Audited
+public class VersionsJoinTableRangeTestEntity extends
+ VersionsJoinTableRangeTestEntitySuperClass {
+
+ private String value;
+
+ /**
+ * Default constructor
+ */
+ public VersionsJoinTableRangeTestEntity() {
+ super();
+ }
+
+ /**
+ * @return the value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * @param value
+ * the value to set
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeTestEntity other = (VersionsJoinTableRangeTestEntity) obj;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponentTestEntity {");
+ output.append(" id = \"").append(getId()).append("\", ");
+ output.append(" genericValue = \"").append(getGenericValue()).append(
+ "\", ");
+ output.append(" value = \"").append(this.value).append("\"}");
+ return output.toString();
+ }
+
+}
Copied: core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java (from rev 15899, core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java)
===================================================================
--- core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java (rev 0)
+++ core/branches/envers-hibernate-3.3/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java 2009-02-05 08:27:17 UTC (rev 15900)
@@ -0,0 +1,85 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Mapped superclass for Audit join table test.
+ *
+ * @author Erik-Berndt Scheper
+ */
+@MappedSuperclass
+(a)org.hibernate.annotations.ForceDiscriminator
+(a)org.hibernate.envers.Audited
+public abstract class VersionsJoinTableRangeTestEntitySuperClass {
+
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String genericValue;
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ protected void setId(Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the genericValue
+ */
+ public String getGenericValue() {
+ return genericValue;
+ }
+
+ /**
+ * @param genericValue
+ * the genericValue to set
+ */
+ public void setGenericValue(String genericValue) {
+ this.genericValue = genericValue;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((genericValue == null) ? 0 : genericValue.hashCode());
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeTestEntitySuperClass other = (VersionsJoinTableRangeTestEntitySuperClass) obj;
+ if (genericValue == null) {
+ if (other.genericValue != null)
+ return false;
+ } else if (!genericValue.equals(other.genericValue))
+ return false;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
+}
15 years, 2 months
Hibernate SVN: r15899 - in core/trunk/envers/src: main/java/org/hibernate/envers/configuration/metadata/reader and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: adamw
Date: 2009-02-05 03:22:40 -0500 (Thu, 05 Feb 2009)
New Revision: 15899
Added:
core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverride.java
core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverrides.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java
core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java
Modified:
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java
Log:
HHH-3729: applying patch with tests
Thank you to Erik-Berndt Scheper for providing the patches!
Added: core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverride.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverride.java (rev 0)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverride.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,41 @@
+package org.hibernate.envers;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * The {@code AuditingOverride} annotation is used to override the auditing
+ * behavior of a field (or property) inside an embedded component.
+ *
+ * @author Erik-Berndt Scheper
+ * @see javax.persistence.Embedded
+ * @see javax.persistence.Embeddable
+ * @see javax.persistence.MappedSuperclass
+ * @see javax.persistence.AssociationOverride
+ * @see AuditJoinTable
+ */
+@Target({ TYPE, METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface AuditOverride {
+
+ /**
+ * @return <strong>Required</strong> Name of the field (or property) whose mapping
+ * is being overridden.
+ */
+ String name();
+
+ /**
+ * @return Indicates if the field (or property) is audited; defaults to {@code true}.
+ */
+ boolean isAudited() default true;
+
+ /**
+ * @return New {@link AuditJoinTable} used for this field (or property). Its value
+ * is ignored if {@link #isAudited()} equals to {@code false}.
+ */
+ AuditJoinTable auditJoinTable() default @AuditJoinTable;
+}
Added: core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverrides.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverrides.java (rev 0)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/AuditOverrides.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,32 @@
+package org.hibernate.envers;
+
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * The {@code AuditingOverrides} annotation is used to override the auditing
+ * behavior for one ore more fields (or properties) inside an embedded
+ * component.
+ *
+ * @author Erik-Berndt Scheper
+ * @see javax.persistence.Embedded
+ * @see javax.persistence.Embeddable
+ * @see javax.persistence.MappedSuperclass
+ * @see javax.persistence.AssociationOverride
+ * @see javax.persistence.AssociationOverrides
+ * @see AuditJoinTable
+ * @see AuditOverride
+ */
+@Target({ TYPE, METHOD, FIELD })
+@Retention(RUNTIME)
+public @interface AuditOverrides {
+ /**
+ * @return An array of {@link AuditOverride} values, to define the new auditing
+ * behavior.
+ */
+ AuditOverride[] value();
+}
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-02-05 03:48:51 UTC (rev 15898)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/AuditedPropertiesReader.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -1,26 +1,31 @@
package org.hibernate.envers.configuration.metadata.reader;
+import static org.hibernate.envers.tools.Tools.newHashSet;
+
+import java.lang.annotation.Annotation;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.JoinColumn;
+import javax.persistence.MapKey;
+import javax.persistence.Version;
+
+import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.envers.AuditJoinTable;
+import org.hibernate.envers.AuditOverride;
+import org.hibernate.envers.AuditOverrides;
+import org.hibernate.envers.Audited;
import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.NotAudited;
-import org.hibernate.envers.Audited;
-import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.configuration.GlobalConfiguration;
-import static org.hibernate.envers.tools.Tools.*;
import org.hibernate.envers.tools.MappingTools;
+import org.hibernate.mapping.Component;
import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Component;
import org.hibernate.mapping.Value;
-import org.hibernate.annotations.common.reflection.XProperty;
-import org.hibernate.annotations.common.reflection.XClass;
import org.jboss.envers.Versioned;
-import javax.persistence.Version;
-import javax.persistence.MapKey;
-import javax.persistence.JoinColumn;
-import java.util.Iterator;
-import java.util.Set;
-import java.lang.annotation.Annotation;
-
/**
* Reads persistent properties form a
* {@link org.hibernate.envers.configuration.metadata.reader.PersistentPropertiesSource}
@@ -28,6 +33,7 @@
* {@link org.hibernate.envers.configuration.metadata.reader.AuditedPropertiesHolder},
* filling all the auditing data.
* @author Adam Warski (adam at warski dot org)
+ * @author Erik-Berndt Scheper
*/
public class AuditedPropertiesReader {
private final ModificationStore defaultStore;
@@ -97,7 +103,6 @@
ComponentAuditingData componentData = new ComponentAuditingData();
isAudited = fillPropertyData(property, componentData, accessType);
- // TODO: component stuff
PersistentPropertiesSource componentPropertiesSource = new ComponentPropertiesSource(
property.getType(), (Component) propertyValue);
new AuditedPropertiesReader(ModificationStore.FULL, componentPropertiesSource, componentData,
@@ -164,6 +169,10 @@
propertyData.setAccessType(accessType);
addPropertyJoinTables(property, propertyData);
+ addPropertyAuditingOverrides(property, propertyData);
+ if (!processPropertyAuditingOverrides(property, propertyData)) {
+ return false; // not audited due to AuditOverride annotation
+ }
addPropertyMapKey(property, propertyData);
return true;
@@ -177,6 +186,7 @@
}
private void addPropertyJoinTables(XProperty property, PropertyAuditingData propertyData) {
+ // first set the join table based on the AuditJoinTable annotation
AuditJoinTable joinTable = property.getAnnotation(AuditJoinTable.class);
if (joinTable != null) {
propertyData.setJoinTable(joinTable);
@@ -185,6 +195,54 @@
}
}
+ /***
+ * Add the {@link org.hibernate.envers.AuditOverride} annotations.
+ *
+ * @param property the property being processed
+ * @param propertyData the Envers auditing data for this property
+ */
+ private void addPropertyAuditingOverrides(XProperty property, PropertyAuditingData propertyData) {
+ AuditOverride annotationOverride = property.getAnnotation(AuditOverride.class);
+ if (annotationOverride != null) {
+ propertyData.addAuditingOverride(annotationOverride);
+ }
+ AuditOverrides annotationOverrides = property.getAnnotation(AuditOverrides.class);
+ if (annotationOverrides != null) {
+ propertyData.addAuditingOverrides(annotationOverrides);
+ }
+ }
+
+ /**
+ * Process the {@link org.hibernate.envers.AuditOverride} annotations for this property.
+ *
+ * @param property
+ * the property for which the {@link org.hibernate.envers.AuditOverride}
+ * annotations are being processed
+ * @param propertyData
+ * the Envers auditing data for this property
+ * @return {@code false} if isAudited() of the override annotation was set to
+ */
+ private boolean processPropertyAuditingOverrides(XProperty property, PropertyAuditingData propertyData) {
+ // if this property is part of a component, process all override annotations
+ if (this.auditedPropertiesHolder instanceof ComponentAuditingData) {
+ List<AuditOverride> overrides = ((ComponentAuditingData) this.auditedPropertiesHolder).getAuditingOverrides();
+ for (AuditOverride override : overrides) {
+ if (property.getName().equals(override.name())) {
+ // the override applies to this property
+ if (!override.isAudited()) {
+ return false;
+ } else {
+ if (override.auditJoinTable() != null) {
+ propertyData.setJoinTable(override.auditJoinTable());
+ }
+ }
+ }
+ }
+
+ }
+ return true;
+ }
+
private static AuditJoinTable DEFAULT_AUDIT_JOIN_TABLE = new AuditJoinTable() {
public String name() { return ""; }
public String schema() { return ""; }
Modified: core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java
===================================================================
--- core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java 2009-02-05 03:48:51 UTC (rev 15898)
+++ core/trunk/envers/src/main/java/org/hibernate/envers/configuration/metadata/reader/PropertyAuditingData.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -24,6 +24,11 @@
*/
package org.hibernate.envers.configuration.metadata.reader;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.hibernate.envers.AuditOverride;
+import org.hibernate.envers.AuditOverrides;
import org.hibernate.envers.ModificationStore;
import org.hibernate.envers.AuditJoinTable;
import org.hibernate.envers.entities.PropertyData;
@@ -38,6 +43,7 @@
private String mapKey;
private AuditJoinTable joinTable;
private String accessType;
+ private final List<AuditOverride> auditJoinTableOverrides = new ArrayList<AuditOverride>(0);
public PropertyAuditingData() {
}
@@ -100,4 +106,33 @@
public PropertyData getPropertyData() {
return new PropertyData(name, beanName, accessType, store);
}
+
+ public List<AuditOverride> getAuditingOverrides() {
+ return auditJoinTableOverrides;
+ }
+
+ public void addAuditingOverride(AuditOverride annotation) {
+ if (annotation != null) {
+ String overrideName = annotation.name();
+ boolean present = false;
+ for (AuditOverride current : auditJoinTableOverrides) {
+ if (current.name().equals(overrideName)) {
+ present = true;
+ break;
+ }
+ }
+ if (!present) {
+ auditJoinTableOverrides.add(annotation);
+ }
+ }
+ }
+
+ public void addAuditingOverrides(AuditOverrides annotationOverrides) {
+ if (annotationOverrides != null) {
+ for (AuditOverride annotation : annotationOverrides.value()) {
+ addAuditingOverride(annotation);
+ }
+ }
+ }
+
}
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponent.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,81 @@
+package org.hibernate.envers.test.integration.naming;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Embeddable;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.OneToMany;
+
+import org.hibernate.annotations.FetchMode;
+
+/**
+ * An embeddable component containing a list of
+ * {@link VersionsJoinTableRangeTestEntitySuperClass}-instances
+ *
+ * @author Erik-Berndt Scheper
+ * @param <T>
+ */
+@Embeddable
+public final class VersionsJoinTableRangeComponent<T extends VersionsJoinTableRangeTestEntitySuperClass> {
+
+ @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+ @org.hibernate.annotations.Fetch(value = FetchMode.SUBSELECT)
+ @org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
+ @JoinColumn(name = "VJTRCTE_ID", insertable = true, updatable = false, nullable = false)
+// Note: If this is processed without override annotation, then we should get a
+// org.hibernate.DuplicateMappingException:
+// Duplicate class/entity mapping JOIN_TABLE_COMPONENT_1_AUD
+ @org.hibernate.envers.AuditJoinTable(name = "JOIN_TABLE_COMPONENT_1_AUD", inverseJoinColumns = @JoinColumn(name = "VJTRTE_ID"))
+ private List<T> range = new ArrayList<T>();
+
+ // ********************** Accessor Methods ********************** //
+
+ protected List<T> getRange() {
+ return this.range;
+ }
+
+ // ********************** Common Methods ********************** //
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((range == null) ? 0 : range.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeComponent<?> other = (VersionsJoinTableRangeComponent<?>) obj;
+ if (range == null) {
+ if (other.range != null)
+ return false;
+ } else if (!range.equals(other.range))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponent {");
+ output.append(" range = \"");
+ for (T instance : range) {
+ output.append(instance).append("\n");
+ }
+ output.append("\"}");
+
+ return output.toString();
+ }
+
+}
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentNamingTest.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,295 @@
+/*
+ * 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.envers.test.integration.naming;
+
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+
+import org.hibernate.ejb.Ejb3Configuration;
+import org.hibernate.envers.test.AbstractEntityTest;
+import org.hibernate.envers.test.entities.components.Component1;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.PersistentClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+/**
+ * Test class for {@link VersionsJoinTableRangeComponentTestEntity}, to test
+ * various {@link org.hibernate.envers.AuditOverride} annotations.
+ *
+ * @author Erik-Berndt Scheper
+ */
+public class VersionsJoinTableRangeComponentNamingTest extends
+ AbstractEntityTest {
+ private Integer vjrcte_id;
+ private Integer vjtrte_id;
+ private Integer vjtrtae_id1;
+
+ public void configure(Ejb3Configuration cfg) {
+ cfg.addAnnotatedClass(VersionsJoinTableRangeComponentTestEntity.class);
+ cfg.addAnnotatedClass(VersionsJoinTableRangeTestEntitySuperClass.class);
+ cfg.addAnnotatedClass(VersionsJoinTableRangeTestEntity.class);
+ cfg.addAnnotatedClass(VersionsJoinTableRangeTestAlternateEntity.class);
+ }
+
+ @BeforeClass(dependsOnMethods = "init")
+ public void initData() {
+
+ // Revision 1
+ EntityManager em = getEntityManager();
+ em.getTransaction().begin();
+
+ // create an instance of the test entity
+ VersionsJoinTableRangeComponentTestEntity vjrcte = new VersionsJoinTableRangeComponentTestEntity();
+ em.persist(vjrcte);
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+
+ vjrcte = em.find(VersionsJoinTableRangeComponentTestEntity.class,
+ vjrcte.getId());
+
+ // create a component containing a list of
+ // VersionsJoinTableRangeTestEntity-instances
+ VersionsJoinTableRangeTestEntity vjtrte = new VersionsJoinTableRangeTestEntity();
+ vjtrte.setGenericValue("generic1");
+ vjtrte.setValue("value1");
+ // and add it to the test entity
+ vjrcte.getComponent1().getRange().add(vjtrte);
+
+ // create a second component containing a list of
+ // VersionsJoinTableRangeTestAlternateEntity-instances
+ VersionsJoinTableRangeTestAlternateEntity vjtrtae1 = new VersionsJoinTableRangeTestAlternateEntity();
+ vjtrtae1.setGenericValue("generic2");
+ vjtrtae1.setAlternateValue("alternateValue2");
+ // and add it to the test entity
+ vjrcte.getComponent2().getRange().add(vjtrtae1);
+
+ // create a third component, and add it to the test entity
+ Component1 simpleComponent = new Component1("string1", "string2");
+ vjrcte.setComponent3(simpleComponent);
+
+ em.persist(vjtrte);
+ em.persist(vjtrtae1);
+ em.persist(vjrcte);
+
+ em.getTransaction().commit();
+
+ // Revision 2
+ em.getTransaction().begin();
+
+ vjrcte = em.find(VersionsJoinTableRangeComponentTestEntity.class,
+ vjrcte.getId());
+ vjtrte = em
+ .find(VersionsJoinTableRangeTestEntity.class, vjtrte.getId());
+ vjtrtae1 = em.find(VersionsJoinTableRangeTestAlternateEntity.class,
+ vjtrtae1.getId());
+
+ assert vjrcte != null;
+ assert vjtrte != null;
+ assert vjtrtae1 != null;
+
+ List<VersionsJoinTableRangeTestEntity> ent1List = vjrcte
+ .getComponent1().getRange();
+ assert ent1List.size() == 1;
+ assert vjtrte.equals(ent1List.get(0));
+
+ List<VersionsJoinTableRangeTestAlternateEntity> ent2List = vjrcte
+ .getComponent2().getRange();
+ assert ent2List.size() == 1;
+ assert vjtrtae1.equals(ent2List.get(0));
+
+ em.getTransaction().commit();
+
+ vjrcte_id = vjrcte.getId();
+ vjtrte_id = vjtrte.getId();
+ vjtrtae_id1 = vjtrtae1.getId();
+ }
+
+ @Test
+ public void testRevisionsCounts() {
+ assert Arrays.asList(1, 2).equals(
+ getAuditReader().getRevisions(
+ VersionsJoinTableRangeComponentTestEntity.class,
+ vjrcte_id));
+ assert Arrays.asList(2).equals(
+ getAuditReader().getRevisions(
+ VersionsJoinTableRangeTestEntity.class, vjtrte_id));
+ assert Arrays.asList(2).equals(
+ getAuditReader().getRevisions(
+ VersionsJoinTableRangeTestAlternateEntity.class,
+ vjtrtae_id1));
+ }
+
+ @Test
+ public void testHistoryOfUniId1() {
+ VersionsJoinTableRangeTestEntity vjtrte = getEntityManager().find(
+ VersionsJoinTableRangeTestEntity.class, vjtrte_id);
+ VersionsJoinTableRangeTestAlternateEntity vjtrtae = getEntityManager()
+ .find(VersionsJoinTableRangeTestAlternateEntity.class,
+ vjtrtae_id1);
+
+ VersionsJoinTableRangeComponentTestEntity rev1 = getAuditReader().find(
+ VersionsJoinTableRangeComponentTestEntity.class, vjrcte_id, 1);
+ VersionsJoinTableRangeComponentTestEntity rev2 = getAuditReader().find(
+ VersionsJoinTableRangeComponentTestEntity.class, vjrcte_id, 2);
+
+ assert rev1.getComponent1().getRange().size() == 0;
+ assert rev1.getComponent2().getRange().size() == 0;
+
+ assert rev2.getComponent1().getRange().size() == 1;
+ assert rev2.getComponent1().getRange().get(0).equals(vjtrte);
+ assert rev2.getComponent2().getRange().size() == 1;
+ assert rev2.getComponent2().getRange().get(0).equals(vjtrtae);
+ }
+
+ /* The Audit join tables we expect */
+ private final static String COMPONENT_1_AUDIT_JOIN_TABLE_NAME = "JOIN_TABLE_COMPONENT_1_AUD";
+ private final static String COMPONENT_2_AUDIT_JOIN_TABLE_NAME = "JOIN_TABLE_COMPONENT_2_AUD";
+
+ /* The Audit join tables that should NOT be there */
+ private final static String UNMODIFIED_COMPONENT_1_AUDIT_JOIN_TABLE_NAME = "VersionsJoinTableRangeComponentTestEntity_VersionsJoinTableRangeTestEntity_AUD";
+ private final static String UNMODIFIED_COMPONENT_2_AUDIT_JOIN_TABLE_NAME = "VersionsJoinTableRangeComponentTestEntity_VersionsJoinTableRangeTestAlternateEntity_AUD";
+
+ @Test
+ public void testExpectedTableNameComponent1() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_1_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+ assert COMPONENT_1_AUDIT_JOIN_TABLE_NAME.equals(auditClass.getTable()
+ .getName());
+ }
+
+ @Test
+ public void testExpectedTableNameComponent2() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_2_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+ assert COMPONENT_2_AUDIT_JOIN_TABLE_NAME.equals(auditClass.getTable()
+ .getName());
+ }
+
+ @Test
+ public void testWrongTableNameComponent1() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ UNMODIFIED_COMPONENT_1_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass == null;
+ }
+
+ @Test
+ public void testWrongTableNameComponent2() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ UNMODIFIED_COMPONENT_2_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass == null;
+ }
+
+ @Test
+ public void testJoinColumnNamesComponent1() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_1_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+
+ @SuppressWarnings( { "unchecked" })
+ Iterator<Column> columns = auditClass.getTable().getColumnIterator();
+
+ boolean id1Found = false;
+ boolean id2Found = false;
+
+ while (columns.hasNext()) {
+ Column column = columns.next();
+ if ("VJTRCTE1_ID".equals(column.getName())) {
+ id1Found = true;
+ }
+
+ if ("VJTRTE_ID".equals(column.getName())) {
+ id2Found = true;
+ }
+ }
+
+ assert id1Found && id2Found;
+ }
+
+ @Test
+ public void testJoinColumnNamesComponent2() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ COMPONENT_2_AUDIT_JOIN_TABLE_NAME);
+ assert auditClass != null;
+
+ @SuppressWarnings( { "unchecked" })
+ Iterator<Column> columns = auditClass.getTable().getColumnIterator();
+
+ boolean id1Found = false;
+ boolean id2Found = false;
+
+ while (columns.hasNext()) {
+ Column column = columns.next();
+ if ("VJTRCTE2_ID".equals(column.getName())) {
+ id1Found = true;
+ }
+
+ if ("VJTRTAE_ID".equals(column.getName())) {
+ id2Found = true;
+ }
+ }
+
+ assert id1Found && id2Found;
+ }
+
+ /**
+ * Verify that
+ * {@link VersionsJoinTableRangeComponentTestEntity#getComponent3()} is
+ * partially audited.
+ */
+ @Test
+ public void testOverrideNotAudited() {
+ PersistentClass auditClass = getCfg().getClassMapping(
+ VersionsJoinTableRangeComponentTestEntity.class.getName()
+ + "_AUD");
+ assert auditClass != null;
+
+ @SuppressWarnings( { "unchecked" })
+ Iterator<Column> columns = auditClass.getTable().getColumnIterator();
+
+ boolean auditColumn1Found = false;
+ boolean auditColumn2Found = false;
+
+ while (columns.hasNext()) {
+ Column column = columns.next();
+ if ("STR1".equals(column.getName())) {
+ auditColumn1Found = true;
+ }
+
+ if ("STR2".equals(column.getName())) {
+ auditColumn2Found = true;
+ }
+ }
+
+ assert auditColumn1Found && !auditColumn2Found;
+ }
+
+}
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeComponentTestEntity.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,190 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.AssociationOverride;
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.Column;
+import javax.persistence.Embedded;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.Table;
+
+import org.hibernate.envers.test.entities.components.Component1;
+import org.hibernate.envers.AuditOverride;
+import org.hibernate.envers.AuditOverrides;
+
+/**
+ * Test entity, containing two embedded components, which each contain a list of
+ * {@link VersionsJoinTableRangeTestEntitySuperClass}-instances
+ *
+ * @author Erik-Berndt Scheper
+ */
+@Entity
+@Table(name = "COMPONENT_TEST_ENTITY")
+public class VersionsJoinTableRangeComponentTestEntity {
+ @Id
+ @GeneratedValue
+ @Column(name = "ID")
+ private Integer id;
+
+ /**
+ * An embedded component, containing a list of
+ * {@link VersionsJoinTableRangeTestEntity}-instances.
+ */
+ @Embedded
+ @AssociationOverride(name = "range", joinColumns = { @JoinColumn(name = "VJTRCTE1_ID", insertable = true, updatable = false, nullable = false) })
+ @org.hibernate.envers.Audited
+ @AuditOverride(name = "range", auditJoinTable = @org.hibernate.envers.AuditJoinTable(name = "JOIN_TABLE_COMPONENT_1_AUD", inverseJoinColumns = @JoinColumn(name = "VJTRTE_ID")))
+ private VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity> component1 = new VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity>();
+
+ /**
+ * An embedded component, containing a list of
+ * {@link VersionsJoinTableRangeTestAlternateEntity}-instances.
+ */
+ @Embedded
+ @AssociationOverride(name = "range", joinColumns = { @JoinColumn(name = "VJTRCTE2_ID", insertable = true, updatable = false, nullable = false) })
+ @org.hibernate.envers.Audited
+ @AuditOverrides(value = { @AuditOverride(name = "range", auditJoinTable = @org.hibernate.envers.AuditJoinTable(name = "JOIN_TABLE_COMPONENT_2_AUD", inverseJoinColumns = @JoinColumn(name = "VJTRTAE_ID"))) })
+ private VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity> component2 = new VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity>();
+
+ /**
+ * An embedded component, containing a list of NOT AUDITED
+ * {@link VersionsJoinTableRangeTestAlternateEntity}-instances.
+ */
+ @Embedded
+ @AttributeOverrides(value={@AttributeOverride(name="str1", column=@Column(name="STR1")), @AttributeOverride(name="str2", column=@Column(name="STR2"))})
+ @org.hibernate.envers.Audited
+ @AuditOverrides(value={@AuditOverride(name="str2", isAudited = false)})
+ private Component1 component3;
+
+ /**
+ * Default constructor
+ */
+ public VersionsJoinTableRangeComponentTestEntity() {
+ super();
+ }
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ protected void setId(Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the component1
+ */
+ public VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity> getComponent1() {
+ return component1;
+ }
+
+ /**
+ * @param component1
+ * the component1 to set
+ */
+ public void setComponent1(
+ VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestEntity> component1) {
+ this.component1 = component1;
+ }
+
+ /**
+ * @return the component2
+ */
+ public VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity> getComponent2() {
+ return component2;
+ }
+
+ /**
+ * @param component2
+ * the component2 to set
+ */
+ public void setComponent2(
+ VersionsJoinTableRangeComponent<VersionsJoinTableRangeTestAlternateEntity> component2) {
+ this.component2 = component2;
+ }
+
+ /**
+ * @return the component3
+ */
+ public Component1 getComponent3() {
+ return component3;
+ }
+
+ /**
+ * @param component3
+ * the component3 to set
+ */
+ public void setComponent3(Component1 component3) {
+ this.component3 = component3;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((component1 == null) ? 0 : component1.hashCode());
+ result = prime * result
+ + ((component2 == null) ? 0 : component2.hashCode());
+ result = prime * result
+ + ((component3 == null) ? 0 : component3.hashCode());
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeComponentTestEntity other = (VersionsJoinTableRangeComponentTestEntity) obj;
+ if (component1 == null) {
+ if (other.component1 != null)
+ return false;
+ } else if (!component1.equals(other.component1))
+ return false;
+ if (component2 == null) {
+ if (other.component2 != null)
+ return false;
+ } else if (!component2.equals(other.component2))
+ return false;
+ if (component3 == null) {
+ if (other.component3 != null)
+ return false;
+ } else if (!component3.equals(other.component3))
+ return false;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponentTestEntity {");
+ output.append(" id = \"").append(this.getId()).append("\",");
+ output.append(" component1 = \"").append(this.component1)
+ .append("\", ");
+ output.append(" component2 = \"").append(this.component2).append("\"}");
+ output.append(" component3 = \"").append(this.component3).append("\"}");
+ return output.toString();
+ }
+
+}
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestAlternateEntity.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,82 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * Alternate implementation of mapped superclass for Audit join table test.
+ *
+ * @author Erik-Berndt Scheper
+ * @see VersionsJoinTableRangeTestEntity
+ * @see VersionsJoinTableRangeTestEntitySuperClass
+ */
+@Entity
+@Table(name = "RANGE_TEST_ALTERNATE_ENTITY")
+(a)org.hibernate.envers.Audited
+public class VersionsJoinTableRangeTestAlternateEntity extends
+ VersionsJoinTableRangeTestEntitySuperClass {
+
+ private String alternateValue;
+
+ /**
+ * Default constructor
+ */
+ public VersionsJoinTableRangeTestAlternateEntity() {
+ super();
+ }
+
+ /**
+ * @return the alternateValue
+ */
+ public String getAlternateValue() {
+ return alternateValue;
+ }
+
+ /**
+ * @param alternateValue
+ * the alternateValue to set
+ */
+ public void setAlternateValue(String alternateValue) {
+ this.alternateValue = alternateValue;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result
+ + ((alternateValue == null) ? 0 : alternateValue.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeTestAlternateEntity other = (VersionsJoinTableRangeTestAlternateEntity) obj;
+ if (alternateValue == null) {
+ if (other.alternateValue != null)
+ return false;
+ } else if (!alternateValue.equals(other.alternateValue))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponentTestEntity {");
+ output.append(" id = \"").append(getId()).append("\", ");
+ output.append(" genericValue = \"").append(getGenericValue()).append(
+ "\", ");
+ output.append(" alternateValue = \"").append(this.alternateValue)
+ .append("\"}");
+ return output.toString();
+ }
+
+}
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntity.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,80 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+/**
+ * Concrete implementation of mapped superclass for Audit join table test.
+ *
+ * @author Erik-Berndt Scheper
+ * @see VersionsJoinTableRangeTestAlternateEntity
+ * @see VersionsJoinTableRangeTestEntitySuperClass
+ */
+@Entity
+@Table(name = "RANGE_TEST_ENTITY")
+(a)org.hibernate.envers.Audited
+public class VersionsJoinTableRangeTestEntity extends
+ VersionsJoinTableRangeTestEntitySuperClass {
+
+ private String value;
+
+ /**
+ * Default constructor
+ */
+ public VersionsJoinTableRangeTestEntity() {
+ super();
+ }
+
+ /**
+ * @return the value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * @param value
+ * the value to set
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((value == null) ? 0 : value.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeTestEntity other = (VersionsJoinTableRangeTestEntity) obj;
+ if (value == null) {
+ if (other.value != null)
+ return false;
+ } else if (!value.equals(other.value))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder output = new StringBuilder();
+
+ output.append("VersionsJoinTableRangeComponentTestEntity {");
+ output.append(" id = \"").append(getId()).append("\", ");
+ output.append(" genericValue = \"").append(getGenericValue()).append(
+ "\", ");
+ output.append(" value = \"").append(this.value).append("\"}");
+ return output.toString();
+ }
+
+}
Added: core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java
===================================================================
--- core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java (rev 0)
+++ core/trunk/envers/src/test/java/org/hibernate/envers/test/integration/naming/VersionsJoinTableRangeTestEntitySuperClass.java 2009-02-05 08:22:40 UTC (rev 15899)
@@ -0,0 +1,85 @@
+package org.hibernate.envers.test.integration.naming;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+
+/**
+ * Mapped superclass for Audit join table test.
+ *
+ * @author Erik-Berndt Scheper
+ */
+@MappedSuperclass
+(a)org.hibernate.annotations.ForceDiscriminator
+(a)org.hibernate.envers.Audited
+public abstract class VersionsJoinTableRangeTestEntitySuperClass {
+
+ @Id
+ @GeneratedValue
+ private Integer id;
+
+ private String genericValue;
+
+ /**
+ * @return the id
+ */
+ public Integer getId() {
+ return id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ protected void setId(Integer id) {
+ this.id = id;
+ }
+
+ /**
+ * @return the genericValue
+ */
+ public String getGenericValue() {
+ return genericValue;
+ }
+
+ /**
+ * @param genericValue
+ * the genericValue to set
+ */
+ public void setGenericValue(String genericValue) {
+ this.genericValue = genericValue;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((genericValue == null) ? 0 : genericValue.hashCode());
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ VersionsJoinTableRangeTestEntitySuperClass other = (VersionsJoinTableRangeTestEntitySuperClass) obj;
+ if (genericValue == null) {
+ if (other.genericValue != null)
+ return false;
+ } else if (!genericValue.equals(other.genericValue))
+ return false;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ return true;
+ }
+
+}
15 years, 2 months
Hibernate SVN: r15898 - in core/branches/Branch_3_2: src/org/hibernate/dialect and 10 other directories.
by hibernate-commits@lists.jboss.org
Author: gbadner
Date: 2009-02-04 22:48:51 -0500 (Wed, 04 Feb 2009)
New Revision: 15898
Added:
core/branches/Branch_3_2/src/org/hibernate/dialect/AbstractTransactSQLDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseASE15Dialect.java
core/branches/Branch_3_2/test/org/hibernate/test/dialect/unit/lockhint/SybaseASE15LockHintsTest.java
Modified:
core/branches/Branch_3_2/etc/hibernate.properties
core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/Sybase11Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseAnywhereDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseDialect.java
core/branches/Branch_3_2/test/org/hibernate/test/AllTests.java
core/branches/Branch_3_2/test/org/hibernate/test/connections/AggressiveReleaseTest.java
core/branches/Branch_3_2/test/org/hibernate/test/generated/TimestampGeneratedValuesWithCachingTest.java
core/branches/Branch_3_2/test/org/hibernate/test/hql/ASTParserLoadingTest.java
core/branches/Branch_3_2/test/org/hibernate/test/hql/HQLTest.java
core/branches/Branch_3_2/test/org/hibernate/test/interfaceproxy/InterfaceProxyTest.java
core/branches/Branch_3_2/test/org/hibernate/test/legacy/FooBarTest.java
core/branches/Branch_3_2/test/org/hibernate/test/legacy/SQLFunctionsTest.java
core/branches/Branch_3_2/test/org/hibernate/test/lob/SerializableTypeTest.java
core/branches/Branch_3_2/test/org/hibernate/test/mixed/MixedTest.java
core/branches/Branch_3_2/test/org/hibernate/test/stats/StatsTest.java
Log:
HHH-3712 : Reorganize the Sybase dialect class hierarchy, add SybaseASE15Dialect, and mark SybaseDialect as deprecated
Modified: core/branches/Branch_3_2/etc/hibernate.properties
===================================================================
--- core/branches/Branch_3_2/etc/hibernate.properties 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/etc/hibernate.properties 2009-02-05 03:48:51 UTC (rev 15898)
@@ -122,6 +122,7 @@
## Sybase
#hibernate.dialect org.hibernate.dialect.SybaseDialect
+#hibernate.dialect org.hibernate.dialect.SybaseASE15Dialect
#hibernate.connection.driver_class com.sybase.jdbc2.jdbc.SybDriver
#hibernate.connection.username sa
#hibernate.connection.password sasasa
Added: core/branches/Branch_3_2/src/org/hibernate/dialect/AbstractTransactSQLDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/AbstractTransactSQLDialect.java (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/AbstractTransactSQLDialect.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -0,0 +1,239 @@
+//$Id: $
+package org.hibernate.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+import java.util.Iterator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.CharIndexFunction;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+
+/**
+ * An abstract base class for Sybase and MS SQL Server dialects.
+ * @author Gavin King
+ */
+
+/* package-private */
+abstract class AbstractTransactSQLDialect extends Dialect {
+ public AbstractTransactSQLDialect() {
+ super();
+ registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values
+ registerColumnType( Types.BIGINT, "numeric(19,0)" );
+ registerColumnType( Types.SMALLINT, "smallint" );
+ registerColumnType( Types.TINYINT, "tinyint" );
+ registerColumnType( Types.INTEGER, "int" );
+ registerColumnType( Types.CHAR, "char(1)" );
+ registerColumnType( Types.VARCHAR, "varchar($l)" );
+ registerColumnType( Types.FLOAT, "float" );
+ registerColumnType( Types.DOUBLE, "double precision" );
+ registerColumnType( Types.DATE, "datetime" );
+ registerColumnType( Types.TIME, "datetime" );
+ registerColumnType( Types.TIMESTAMP, "datetime" );
+ registerColumnType( Types.VARBINARY, "varbinary($l)" );
+ registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+ registerColumnType( Types.BLOB, "image" );
+ registerColumnType( Types.CLOB, "text" );
+
+ registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+ registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
+ registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) );
+ registerFunction( "lower", new StandardSQLFunction("lower") );
+ registerFunction( "upper", new StandardSQLFunction("upper") );
+ registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) );
+ registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
+ registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
+ registerFunction( "reverse", new StandardSQLFunction("reverse") );
+ registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) );
+
+ registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) );
+
+ registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
+ registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) );
+ registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) );
+
+ registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
+ registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) );
+ registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) );
+ registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) );
+ registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) );
+ registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) );
+
+ registerFunction( "abs", new StandardSQLFunction("abs") );
+ registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+ registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+ registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+ registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+ registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+ registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
+ registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+ registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) );
+ registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
+ registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+ registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+ registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+ registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
+ registerFunction( "square", new StandardSQLFunction("square") );
+ registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) );
+
+ registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
+ registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
+
+ registerFunction( "round", new StandardSQLFunction("round") );
+ registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
+ registerFunction( "floor", new StandardSQLFunction("floor") );
+
+ registerFunction( "isnull", new StandardSQLFunction("isnull") );
+
+ registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) );
+
+ registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
+ registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );
+ registerFunction( "locate", new CharIndexFunction() );
+
+ getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+ }
+
+ public String getAddColumnString() {
+ return "add";
+ }
+ public String getNullColumnString() {
+ return " null";
+ }
+ public boolean qualifyIndexName() {
+ return false;
+ }
+
+ public String getForUpdateString() {
+ return "";
+ }
+
+ public boolean supportsIdentityColumns() {
+ return true;
+ }
+ public String getIdentitySelectString() {
+ return "select @@identity";
+ }
+ public String getIdentityColumnString() {
+ return "identity not null"; //starts with 1, implicitly
+ }
+
+ public boolean supportsInsertSelectIdentity() {
+ return true;
+ }
+
+ public String appendIdentitySelectToInsert(String insertSQL) {
+ return insertSQL + "\nselect @@identity";
+ }
+
+ public String appendLockHint(LockMode mode, String tableName) {
+ if ( mode.greaterThan( LockMode.READ ) ) {
+ return tableName + " holdlock";
+ }
+ else {
+ return tableName;
+ }
+ }
+
+ public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
+ Iterator itr = aliasedLockModes.entrySet().iterator();
+ StringBuffer buffer = new StringBuffer( sql );
+ int correction = 0;
+ while ( itr.hasNext() ) {
+ final Map.Entry entry = ( Map.Entry ) itr.next();
+ final LockMode lockMode = ( LockMode ) entry.getValue();
+ if ( lockMode.greaterThan( LockMode.READ ) ) {
+ final String alias = ( String ) entry.getKey();
+ int start = -1, end = -1;
+ if ( sql.endsWith( " " + alias ) ) {
+ start = ( sql.length() - alias.length() ) + correction;
+ end = start + alias.length();
+ }
+ else {
+ int position = sql.indexOf( " " + alias + " " );
+ if ( position <= -1 ) {
+ position = sql.indexOf( " " + alias + "," );
+ }
+ if ( position > -1 ) {
+ start = position + correction + 1;
+ end = start + alias.length();
+ }
+ }
+
+ if ( start > -1 ) {
+ final String lockHint = appendLockHint( lockMode, alias );
+ buffer.replace( start, end, lockHint );
+ correction += ( lockHint.length() - alias.length() );
+ }
+ }
+ }
+ return buffer.toString();
+ }
+
+ public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+ return col; // sql server just returns automatically
+ }
+
+ public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+ boolean isResultSet = ps.execute();
+// This assumes you will want to ignore any update counts
+ while ( !isResultSet && ps.getUpdateCount() != -1 ) {
+ isResultSet = ps.getMoreResults();
+ }
+// You may still have other ResultSets or update counts left to process here
+// but you can't do it now or the ResultSet you just got will be closed
+ return ps.getResultSet();
+ }
+
+ public boolean supportsCurrentTimestampSelection() {
+ return true;
+ }
+
+ public boolean isCurrentTimestampSelectStringCallable() {
+ return false;
+ }
+
+ public String getCurrentTimestampSelectString() {
+ return "select getdate()";
+ }
+
+ public boolean supportsTemporaryTables() {
+ return true;
+ }
+
+ public String generateTemporaryTableName(String baseTableName) {
+ return "#" + baseTableName;
+ }
+
+ public boolean dropTemporaryTableAfterUse() {
+ return true; // sql-server, at least needed this dropped after use; strange!
+ }
+
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsEmptyInList() {
+ return false;
+ }
+
+ public boolean supportsExistsInSelect() {
+ return false;
+ }
+
+ public boolean doesReadCommittedCauseWritersToBlockReaders() {
+ return true;
+ }
+
+ public boolean doesRepeatableReadCauseReadersToBlockWriters() {
+ return true;
+ }
+}
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -14,14 +14,18 @@
*
* @author Gavin King
*/
-public class SQLServerDialect extends SybaseDialect {
+public class SQLServerDialect extends AbstractTransactSQLDialect {
public SQLServerDialect() {
registerColumnType( Types.VARBINARY, "image" );
registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
+ registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
+ registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
+ registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
registerFunction( "locate", new StandardSQLFunction("charindex", Hibernate.INTEGER) );
+ registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) );
registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) );
@@ -112,10 +116,6 @@
return false;
}
- public boolean supportsCascadeDelete() {
- return true;
- }
-
public boolean supportsCircularCascadeDeleteConstraints() {
// SQL Server (at least up through 2005) does not support defining
// cascade delete constraints which can circel back to the mutating
@@ -123,10 +123,6 @@
return false;
}
- public boolean supportsExpectedLobUsagePattern() {
- return true;
- }
-
public boolean supportsLobValueChangePropogation() {
// note: at least my local SQL Server 2005 Express shows this not working...
return false;
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/Sybase11Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/Sybase11Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/Sybase11Dialect.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -8,7 +8,7 @@
* A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax)
* @author Colm O' Flaherty
*/
-public class Sybase11Dialect extends SybaseDialect {
+public class Sybase11Dialect extends AbstractTransactSQLDialect {
public Sybase11Dialect() {
super();
}
Added: core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseASE15Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseASE15Dialect.java (rev 0)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseASE15Dialect.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -0,0 +1,43 @@
+//$Id: SybaseDialect.java 15760 2009-01-09 09:52:13Z gbadner $
+package org.hibernate.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+import java.util.Iterator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.CharIndexFunction;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+
+/**
+ * An SQL dialect compatible with Sybase and MS SQL Server.
+ * @author Gavin King
+ */
+
+public class SybaseASE15Dialect extends AbstractTransactSQLDialect {
+ public SybaseASE15Dialect() {
+ super();
+ registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
+ registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
+ registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
+ registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
+ }
+
+ // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public boolean supportsCascadeDelete() {
+ return false;
+ }
+
+ public boolean supportsExpectedLobUsagePattern() {
+ return false;
+ }
+}
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseAnywhereDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseAnywhereDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseAnywhereDialect.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -6,7 +6,7 @@
* (Tested on ASA 8.x)
* @author ?
*/
-public class SybaseAnywhereDialect extends SybaseDialect {
+public class SybaseAnywhereDialect extends AbstractTransactSQLDialect {
/**
* Sybase Anywhere syntax would require a "DEFAULT" for each column specified,
@@ -29,4 +29,4 @@
return false;
}
-}
\ No newline at end of file
+}
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/SybaseDialect.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -1,253 +1,16 @@
//$Id$
package org.hibernate.dialect;
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Map;
-import java.util.Iterator;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.CharIndexFunction;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-
/**
- * An SQL dialect compatible with Sybase and MS SQL Server.
- * @author Gavin King
+ * SybaseDialect is being deprecated.
+ *
+ * AbstractTransactSQLDialect should be used as a base
+ * class for Sybase and MS SQL Server dialects.
+ *
+ * @author Gail Badner
+ * @deprecated SybaseASE15Dialect or SQLServerDialect should be
+ * used instead.
*/
-public class SybaseDialect extends Dialect {
- public SybaseDialect() {
- super();
- registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values
- registerColumnType( Types.BIGINT, "numeric(19,0)" );
- registerColumnType( Types.SMALLINT, "smallint" );
- registerColumnType( Types.TINYINT, "tinyint" );
- registerColumnType( Types.INTEGER, "int" );
- registerColumnType( Types.CHAR, "char(1)" );
- registerColumnType( Types.VARCHAR, "varchar($l)" );
- registerColumnType( Types.FLOAT, "float" );
- registerColumnType( Types.DOUBLE, "double precision" );
- registerColumnType( Types.DATE, "datetime" );
- registerColumnType( Types.TIME, "datetime" );
- registerColumnType( Types.TIMESTAMP, "datetime" );
- registerColumnType( Types.VARBINARY, "varbinary($l)" );
- registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
- registerColumnType( Types.BLOB, "image" );
- registerColumnType( Types.CLOB, "text" );
-
- registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
- registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
- registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) );
- registerFunction( "lower", new StandardSQLFunction("lower") );
- registerFunction( "upper", new StandardSQLFunction("upper") );
- registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) );
- registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
- registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
- registerFunction( "reverse", new StandardSQLFunction("reverse") );
- registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) );
-
- registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) );
-
- registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
- registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) );
- registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) );
-
- registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
- registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) );
- registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) );
- registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) );
- registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) );
- registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) );
- registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(second, ?1)") );
- registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(minute, ?1)") );
- registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "datepart(hour, ?1)") );
- registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
-
- registerFunction( "abs", new StandardSQLFunction("abs") );
- registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
- registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
- registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
- registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
- registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
- registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
- registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
- registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) );
- registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
- registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
- registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
- registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
- registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
- registerFunction( "square", new StandardSQLFunction("square") );
- registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) );
-
- registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
- registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
-
- registerFunction( "round", new StandardSQLFunction("round") );
- registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
- registerFunction( "floor", new StandardSQLFunction("floor") );
-
- registerFunction( "isnull", new StandardSQLFunction("isnull") );
-
- registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) );
-
- registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
- registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );
- registerFunction( "locate", new CharIndexFunction() );
-
- registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) );
- registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) );
-
- getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
- }
-
- public String getAddColumnString() {
- return "add";
- }
- public String getNullColumnString() {
- return " null";
- }
- public boolean qualifyIndexName() {
- return false;
- }
-
- public String getForUpdateString() {
- return "";
- }
-
- public boolean supportsIdentityColumns() {
- return true;
- }
- public String getIdentitySelectString() {
- return "select @@identity";
- }
- public String getIdentityColumnString() {
- return "identity not null"; //starts with 1, implicitly
- }
-
- public boolean supportsInsertSelectIdentity() {
- return true;
- }
-
- public String appendIdentitySelectToInsert(String insertSQL) {
- return insertSQL + "\nselect @@identity";
- }
-
- public String appendLockHint(LockMode mode, String tableName) {
- if ( mode.greaterThan( LockMode.READ ) ) {
- return tableName + " holdlock";
- }
- else {
- return tableName;
- }
- }
-
- public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
- Iterator itr = aliasedLockModes.entrySet().iterator();
- StringBuffer buffer = new StringBuffer( sql );
- int correction = 0;
- while ( itr.hasNext() ) {
- final Map.Entry entry = ( Map.Entry ) itr.next();
- final LockMode lockMode = ( LockMode ) entry.getValue();
- if ( lockMode.greaterThan( LockMode.READ ) ) {
- final String alias = ( String ) entry.getKey();
- int start = -1, end = -1;
- if ( sql.endsWith( " " + alias ) ) {
- start = ( sql.length() - alias.length() ) + correction;
- end = start + alias.length();
- }
- else {
- int position = sql.indexOf( " " + alias + " " );
- if ( position <= -1 ) {
- position = sql.indexOf( " " + alias + "," );
- }
- if ( position > -1 ) {
- start = position + correction + 1;
- end = start + alias.length();
- }
- }
-
- if ( start > -1 ) {
- final String lockHint = appendLockHint( lockMode, alias );
- buffer.replace( start, end, lockHint );
- correction += ( lockHint.length() - alias.length() );
- }
- }
- }
- return buffer.toString();
- }
-
- public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
- return col; // sql server just returns automatically
- }
-
- public ResultSet getResultSet(CallableStatement ps) throws SQLException {
- boolean isResultSet = ps.execute();
-// This assumes you will want to ignore any update counts
- while ( !isResultSet && ps.getUpdateCount() != -1 ) {
- isResultSet = ps.getMoreResults();
- }
-// You may still have other ResultSets or update counts left to process here
-// but you can't do it now or the ResultSet you just got will be closed
- return ps.getResultSet();
- }
-
- public boolean supportsCurrentTimestampSelection() {
- return true;
- }
-
- public boolean isCurrentTimestampSelectStringCallable() {
- return false;
- }
-
- public String getCurrentTimestampSelectString() {
- return "select getdate()";
- }
-
- public boolean supportsTemporaryTables() {
- return true;
- }
-
- public String generateTemporaryTableName(String baseTableName) {
- return "#" + baseTableName;
- }
-
- public boolean dropTemporaryTableAfterUse() {
- return true; // sql-server, at least needed this dropped after use; strange!
- }
-
-
- // Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- public boolean supportsCascadeDelete() {
- return false;
- }
-
- public boolean supportsExpectedLobUsagePattern() {
- return false;
- }
-
- public boolean supportsEmptyInList() {
- return false;
- }
-
- public boolean supportsExistsInSelect() {
- return false;
- }
-
- public boolean doesReadCommittedCauseWritersToBlockReaders() {
- return true;
- }
-
- public boolean doesRepeatableReadCauseReadersToBlockWriters() {
- return true;
- }
+public class SybaseDialect extends AbstractTransactSQLDialect {
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/AllTests.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/AllTests.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/AllTests.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -44,6 +44,7 @@
import org.hibernate.test.deletetransient.DeleteTransientEntityTest;
import org.hibernate.test.dialect.functional.cache.SQLFunctionsInterSystemsTest;
import org.hibernate.test.dialect.unit.lockhint.SQLServerLockHintsTest;
+import org.hibernate.test.dialect.unit.lockhint.SybaseASE15LockHintsTest;
import org.hibernate.test.dialect.unit.lockhint.SybaseLockHintsTest;
import org.hibernate.test.discriminator.DiscriminatorTest;
import org.hibernate.test.dynamicentity.interceptor.InterceptorDynamicEntityTest;
@@ -500,6 +501,7 @@
suite.addTest( LazyKeyManyToOneTest.suite() );
suite.addTest( EagerKeyManyToOneTest.suite() );
suite.addTest( SQLFunctionsInterSystemsTest.suite() );
+ suite.addTest( SybaseASE15LockHintsTest.suite() );
suite.addTest( SybaseLockHintsTest.suite() );
suite.addTest( SQLServerLockHintsTest.suite() );
suite.addTest( InsertOrderingTest.suite() );
Modified: core/branches/Branch_3_2/test/org/hibernate/test/connections/AggressiveReleaseTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/connections/AggressiveReleaseTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/connections/AggressiveReleaseTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -107,7 +107,7 @@
// expected behavior
}
- // getting the first row only because Sybase throws NullPointerException
+ // getting the first row only because SybaseASE15Dialect throws NullPointerException
// if data is not read before closing the ResultSet
sr.next();
Added: core/branches/Branch_3_2/test/org/hibernate/test/dialect/unit/lockhint/SybaseASE15LockHintsTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/dialect/unit/lockhint/SybaseASE15LockHintsTest.java (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/dialect/unit/lockhint/SybaseASE15LockHintsTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -0,0 +1,32 @@
+//$Id $
+package org.hibernate.test.dialect.unit.lockhint;
+
+import junit.framework.TestSuite;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Gail Badner
+ */
+public class SybaseASE15LockHintsTest extends AbstractLockHintTest {
+ public static final Dialect DIALECT = new SybaseASE15Dialect();
+
+ public SybaseASE15LockHintsTest(String string) {
+ super( string );
+ }
+
+ protected String getLockHintUsed() {
+ return "holdlock";
+ }
+
+ protected Dialect getDialectUnderTest() {
+ return DIALECT;
+ }
+
+ public static TestSuite suite() {
+ return new TestSuite( SybaseASE15LockHintsTest.class );
+ }
+}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/generated/TimestampGeneratedValuesWithCachingTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/generated/TimestampGeneratedValuesWithCachingTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/generated/TimestampGeneratedValuesWithCachingTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -5,6 +5,10 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseAnywhereDialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
/**
@@ -25,7 +29,9 @@
public boolean appliesTo(Dialect dialect) {
// this test is specific to Sybase/SQLServer as it is testing support
// for their TIMESTAMP datatype...
- return ( dialect instanceof SybaseDialect );
+ return ( dialect instanceof SybaseDialect || dialect instanceof Sybase11Dialect ||
+ dialect instanceof SybaseAnywhereDialect || dialect instanceof SybaseASE15Dialect ||
+ dialect instanceof SQLServerDialect);
}
public static Test suite() {
Modified: core/branches/Branch_3_2/test/org/hibernate/test/hql/ASTParserLoadingTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -33,6 +33,9 @@
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.hql.ast.ASTQueryTranslatorFactory;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -1218,7 +1221,7 @@
if ( getDialect() instanceof DB2Dialect ) {
assertTrue( str.startsWith("1.234") );
}
- else if ( getDialect() instanceof SybaseDialect ) {
+ else if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect || getDialect() instanceof SQLServerDialect ) {
// str(val) on sybase assumes a default of 10 characters with no decimal point or decimal values
// str(val) on sybase result is right-justified
assertEquals( str.length(), 10 );
@@ -1230,7 +1233,7 @@
else {
assertTrue( str.startsWith("123.4") );
}
- if ( ! ( getDialect() instanceof SybaseDialect ) ) {
+ if ( ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && ! ( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SybaseAnywhereDialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
// In TransactSQL (the variant spoken by Sybase and SQLServer), the str() function
// is explicitly intended for numeric values only...
String dateStr1 = (String) session.createQuery("select str(current_date) from Animal").uniqueResult();
Modified: core/branches/Branch_3_2/test/org/hibernate/test/hql/HQLTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/hql/HQLTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/hql/HQLTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -19,7 +19,11 @@
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.query.HQLQueryPlan;
@@ -220,11 +224,14 @@
assertTranslation("from Animal a where abs(:param - a.bodyWeight) < 2.0");
assertTranslation("from Animal where abs(:x - :y) < 2.0");
assertTranslation("from Animal where lower(upper(:foo)) like 'f%'");
- if ( ! ( getDialect() instanceof SybaseDialect ) ) {
- // SybaseDialect maps the length function -> len; classic translator does not consider that *when nested*
+ if ( ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && ! ( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
+ // Transact-SQL dialects (except SybaseAnywhereDialect) map the length function -> len;
+ // classic translator does not consider that *when nested*;
+ // SybaseAnywhereDialect supports the length function
+
assertTranslation("from Animal a where abs(abs(a.bodyWeight - 1.0 + :param) * abs(length('ffobar')-3)) = 3.0");
}
- if ( !( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect ) ) {
+ if ( !( getDialect() instanceof MySQLDialect ) && ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && !( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SybaseAnywhereDialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
assertTranslation("from Animal where lower(upper('foo') || upper(:bar)) like 'f%'");
}
if ( getDialect() instanceof PostgreSQLDialect ) {
@@ -595,7 +602,8 @@
}
public void testConcatenation() {
- if ( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect ) {
+ if ( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect || getDialect() instanceof SQLServerDialect ) {
+ // SybaseASE15Dialect and SybaseAnywhereDialect support '||'
// MySQL uses concat(x, y, z)
// SQL Server replaces '||' with '+'
//
Modified: core/branches/Branch_3_2/test/org/hibernate/test/interfaceproxy/InterfaceProxyTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/interfaceproxy/InterfaceProxyTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/interfaceproxy/InterfaceProxyTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -46,7 +46,7 @@
SecureDocument d2 = new SecureDocumentImpl();
d2.setName("Secret");
d2.setContent( Hibernate.createBlob( "wxyz wxyz".getBytes() ) );
- // Sybase only allows 7-bits in a byte to be inserted into a tinyint
+ // SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128)
d2.setPermissionBits( (byte) 127 );
d2.setOwner("gavin");
Modified: core/branches/Branch_3_2/test/org/hibernate/test/legacy/FooBarTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/legacy/FooBarTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/legacy/FooBarTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -56,6 +56,8 @@
import org.hibernate.dialect.SAPDBDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.jmx.HibernateService;
@@ -2127,7 +2129,8 @@
s.find("select count(*) from Baz as baz where 1 in indices(baz.fooArray)");
s.find("select count(*) from Bar as bar where 'abc' in elements(bar.baz.fooArray)");
s.find("select count(*) from Bar as bar where 1 in indices(bar.baz.fooArray)");
- if ( !(getDialect() instanceof DB2Dialect) && !(getDialect() instanceof Oracle8iDialect ) && !( getDialect() instanceof SybaseDialect && !(getDialect() instanceof SQLServerDialect ) ) ) {
+ if ( !(getDialect() instanceof DB2Dialect) && !(getDialect() instanceof Oracle8iDialect ) && !( getDialect() instanceof SybaseDialect ) && !( getDialect() instanceof Sybase11Dialect ) && !( getDialect() instanceof SybaseASE15Dialect ) ) {
+ // SybaseAnywhereDialect supports implicit conversions from strings to ints
s.find("select count(*) from Bar as bar, bar.component.glarch.proxyArray as g where g.id in indices(bar.baz.fooArray)");
s.find("select max( elements(bar.baz.fooArray) ) from Bar as bar, bar.component.glarch.proxyArray as g where g.id in indices(bar.baz.fooArray)");
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/legacy/SQLFunctionsTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/legacy/SQLFunctionsTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/legacy/SQLFunctionsTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -24,6 +24,9 @@
import org.hibernate.dialect.MckoiDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.SybaseDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.TimesTenDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.Oracle9iDialect;
@@ -368,7 +371,7 @@
s.find("from Simple s where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )").size()==1
);
}
- if ( !(getDialect() instanceof MySQLDialect) && !(getDialect() instanceof SybaseDialect) && !(getDialect() instanceof MckoiDialect) && !(getDialect() instanceof InterbaseDialect) && !(getDialect() instanceof TimesTenDialect) ) { //My SQL has a funny concatenation operator
+ if ( !(getDialect() instanceof MySQLDialect) && !(getDialect() instanceof SybaseDialect) && !(getDialect() instanceof SQLServerDialect) && !(getDialect() instanceof MckoiDialect) && !(getDialect() instanceof InterbaseDialect) && !(getDialect() instanceof TimesTenDialect) ) { //My SQL has a funny concatenation operator
assertTrue(
s.find("from Simple s where lower( s.name || ' foo' ) ='simple 1 foo'").size()==1
);
@@ -498,8 +501,8 @@
//assertTrue( b.getClob() instanceof ClobImpl );
s.flush();
- // Sybase ASE does not support ResultSet.getBlob(String)
- if ( getDialect() instanceof SybaseDialect && ! ( getDialect() instanceof SQLServerDialect ) ) {
+ // Sybase does not support ResultSet.getBlob(String)
+ if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect ) {
s.connection().rollback();
s.close();
return;
Modified: core/branches/Branch_3_2/test/org/hibernate/test/lob/SerializableTypeTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/lob/SerializableTypeTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/lob/SerializableTypeTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -30,7 +30,9 @@
import org.hibernate.Session;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.SybaseDialect;
-import org.hibernate.dialect.SQLServerDialect;
+import org.hibernate.dialect.Sybase11Dialect;
+import org.hibernate.dialect.SybaseASE15Dialect;
+import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -59,8 +61,8 @@
}
public void testNewSerializableType() {
- // Sybase ASE does not support ResultSet.getBlob(String)
- if ( getDialect() instanceof SybaseDialect && ! ( getDialect() instanceof SQLServerDialect ) ) {
+ // Sybase dialects do not support ResultSet.getBlob(String)
+ if ( getDialect() instanceof SybaseDialect || getDialect() instanceof Sybase11Dialect || getDialect() instanceof SybaseASE15Dialect || getDialect() instanceof SybaseAnywhereDialect ) {
return;
}
Modified: core/branches/Branch_3_2/test/org/hibernate/test/mixed/MixedTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/mixed/MixedTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/mixed/MixedTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -46,7 +46,7 @@
SecureDocument d2 = new SecureDocument();
d2.setName( "Secret" );
d2.setContent( Hibernate.createBlob( "wxyz wxyz".getBytes() ) );
- // Sybase only allows 7-bits in a byte to be inserted into a tinyint
+ // SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128)
d2.setPermissionBits( (byte) 127 );
d2.setOwner( "gavin" );
@@ -96,7 +96,7 @@
assertNotNull( d2.getContent() );
assertEquals( "max", d2.getOwner() );
assertEquals( "/", d2.getParent().getName() );
- // Sybase only allows 7-bits in a byte to be inserted into a tinyint
+ // SybaseASE15Dialect only allows 7-bits in a byte to be inserted into a tinyint
// column (0 <= val < 128)
assertEquals( (byte) 127, d2.getPermissionBits() );
assertNotNull( d2.getCreated() );
Modified: core/branches/Branch_3_2/test/org/hibernate/test/stats/StatsTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/stats/StatsTest.java 2009-02-04 23:14:05 UTC (rev 15897)
+++ core/branches/Branch_3_2/test/org/hibernate/test/stats/StatsTest.java 2009-02-05 03:48:51 UTC (rev 15898)
@@ -165,7 +165,7 @@
// same deal with scroll()...
assertEquals( "unexpected execution count", 3, continentStats.getExecutionCount() );
assertEquals( "unexpected row count", results, continentStats.getExecutionRowCount() );
- // scroll through data because Sybase throws NullPointerException
+ // scroll through data because SybaseASE15Dialect throws NullPointerException
// if data is not read before closing the ResultSet
while ( scrollableResults.next() ) {
// do nothing
15 years, 2 months
Hibernate SVN: r15897 - in core/branches/Branch_3_2/src/org/hibernate: loader and 1 other directory.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-04 18:14:05 -0500 (Wed, 04 Feb 2009)
New Revision: 15897
Modified:
core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java
core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java
core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java
Log:
HHH-3750 : dialect first-result handling
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/Cache71Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -32,9 +32,9 @@
import org.hibernate.util.StringHelper;
/**
- * Caché 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Cach� SQL.<br>
+ * Caché 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Cach� SQL.<br>
* <br>
- * Compatible with Cach� 2007.1.
+ * Compatible with Cach� 2007.1.
* <br>
* <head>
* <title>Caché and Hibernate</title>
@@ -189,8 +189,8 @@
public class Cache71Dialect extends Dialect {
/**
- * Creates new <code>Cach�71Dialect</code> instance. Sets up the JDBC /
- * Cach� type mappings.
+ * Creates new <code>Cach�71Dialect</code> instance. Sets up the JDBC /
+ * Cach� type mappings.
*/
public Cache71Dialect() {
super();
@@ -575,7 +575,7 @@
public String getLimitString(String sql, boolean hasOffset) {
if ( hasOffset ) {
- throw new UnsupportedOperationException( "An offset may not be specified to <TOP n> in Cache SQL" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DB2390Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -25,15 +25,6 @@
return false;
}
- public String getLimitString(String sql, int offset, int limit) {
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
- }
-
public boolean useMaxForLimit() {
return true;
}
@@ -42,4 +33,16 @@
return false;
}
+ public String getLimitString(String sql, int offset, int limit) {
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
+ }
+
}
\ No newline at end of file
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DB2400Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -1,11 +1,11 @@
package org.hibernate.dialect;
/**
-* An SQL dialect for DB2/400
-* @author Peter DeGregorio (pdegregorio)
-* This class provides support for DB2 Universal Database for iSeries,
-* also known as DB2/400.
-*/
+ * An SQL dialect for DB2/400. This class provides support for DB2 Universal Database for iSeries,
+ * also known as DB2/400.
+ *
+ * @author Peter DeGregorio (pdegregorio)
+ */
public class DB2400Dialect extends DB2Dialect {
public boolean supportsSequences() {
@@ -24,15 +24,6 @@
return false;
}
- public String getLimitString(String sql, int offset, int limit) {
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
- }
-
public boolean useMaxForLimit() {
return true;
}
@@ -41,4 +32,16 @@
return false;
}
+ public String getLimitString(String sql, int offset, int limit) {
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
+ }
+
}
\ No newline at end of file
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/DB2Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -220,21 +220,20 @@
}
public String getLimitString(String sql, boolean hasOffset) {
-
int startOfSelect = sql.toLowerCase().indexOf("select");
StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
- .append( sql.substring(0, startOfSelect) ) //add the comment
- .append("select * from ( select ") //nest the main query in an outer select
- .append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list
+ .append( sql.substring(0, startOfSelect) ) // add the comment
+ .append("select * from ( select ") // nest the main query in an outer select
+ .append( getRowNumber(sql) ); // add the rownnumber bit into the outer query select list
if ( hasDistinct(sql) ) {
- pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
- .append( sql.substring(startOfSelect) ) //add the main query
- .append(" ) as row_"); //close off the inner nested select
+ pagingSelect.append(" row_.* from ( ") // add another (inner) nested select
+ .append( sql.substring(startOfSelect) ) // add the main query
+ .append(" ) as row_"); // close off the inner nested select
}
else {
- pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query
+ pagingSelect.append( sql.substring( startOfSelect + 6 ) ); // add the main query
}
pagingSelect.append(" ) as temp_ where rownumber_ ");
@@ -250,6 +249,18 @@
return pagingSelect.toString();
}
+ /**
+ * DB2 does have a one-based offset, however this was actually already handled in the limiot string building
+ * (the '?+1' bit). To not mess up inheritors, I'll leave that part alone and not touch the offset here.
+ *
+ * @param zeroBasedFirstResult The user-supplied, zero-based offset
+ *
+ * @return zeroBasedFirstResult
+ */
+ public int convertToFirstRowValue(int zeroBasedFirstResult) {
+ return zeroBasedFirstResult;
+ }
+
private static boolean hasDistinct(String sql) {
return sql.toLowerCase().indexOf("select distinct")>=0;
}
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -872,7 +872,26 @@
throw new UnsupportedOperationException( "paged queries not supported" );
}
+ /**
+ * Hibernate APIs explcitly state that setFirstResult() should be a zero-based offset. Here we allow the
+ * Dialect a chance to convert that value based on what the underlying db or driver will expect.
+ * <p/>
+ * NOTE: what gets passed into {@link #getLimitString(String,int,int)} is the zero-based offset. Dialects which
+ * do not {@link #supportsVariableLimit} should take care to perform any needed {@link #convertToFirstRowValue}
+ * calls prior to injecting the limit values into the SQL string.
+ *
+ * @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
+ *
+ * @return The corresponding db/dialect specific offset.
+ *
+ * @see org.hibernate.Query#setFirstResult
+ * @see org.hibernate.Criteria#setFirstResult
+ */
+ public int convertToFirstRowValue(int zeroBasedFirstResult) {
+ return zeroBasedFirstResult;
+ }
+
// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/FirebirdDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -3,6 +3,7 @@
/**
* An SQL dialect for Firebird.
+ *
* @author Reha CENANI
*/
public class FirebirdDialect extends InterbaseDialect {
@@ -12,10 +13,10 @@
}
public String getLimitString(String sql, boolean hasOffset) {
- return new StringBuffer( sql.length()+20 )
- .append(sql)
- .insert(6, hasOffset ? " first ? skip ?" : " first ?")
- .toString();
+ return new StringBuffer( sql.length() + 20 )
+ .append( sql )
+ .insert( 6, hasOffset ? " first ? skip ?" : " first ?" )
+ .toString();
}
public boolean bindLimitParametersFirst() {
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/InformixDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -84,28 +84,27 @@
* @return String
*/
public String getAddForeignKeyConstraintString(
- String constraintName,
- String[] foreignKey,
- String referencedTable,
- String[] primaryKey, boolean referencesPrimaryKey
- ) {
- StringBuffer result = new StringBuffer(30);
-
- result.append(" add constraint ")
- .append(" foreign key (")
- .append( StringHelper.join(", ", foreignKey) )
- .append(") references ")
- .append(referencedTable);
-
- if(!referencesPrimaryKey) {
- result.append(" (")
- .append( StringHelper.join(", ", primaryKey) )
- .append(')');
+ String constraintName,
+ String[] foreignKey,
+ String referencedTable,
+ String[] primaryKey,
+ boolean referencesPrimaryKey) {
+ StringBuffer result = new StringBuffer( 30 )
+ .append( " add constraint " )
+ .append( " foreign key (" )
+ .append( StringHelper.join( ", ", foreignKey ) )
+ .append( ") references " )
+ .append( referencedTable );
+
+ if ( !referencesPrimaryKey ) {
+ result.append( " (" )
+ .append( StringHelper.join( ", ", primaryKey ) )
+ .append( ')' );
}
- result.append(" constraint ").append(constraintName);
-
- return result.toString();
+ result.append( " constraint " ).append( constraintName );
+
+ return result.toString();
}
/**
@@ -149,11 +148,13 @@
}
public String getLimitString(String querySelect, int offset, int limit) {
- if (offset>0) throw new UnsupportedOperationException("informix has no offset");
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
- .toString();
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
+ .toString();
}
public boolean supportsVariableLimit() {
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/IngresDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -234,7 +234,7 @@
*/
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "offset not supported" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( querySelect.length() + 16 )
.append( querySelect )
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/MySQLDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -213,38 +213,12 @@
}
public String getLimitString(String sql, boolean hasOffset) {
- return new StringBuffer( sql.length()+20 )
- .append(sql)
- .append( hasOffset ? " limit ?, ?" : " limit ?")
- .toString();
+ return new StringBuffer( sql.length() + 20 )
+ .append( sql )
+ .append( hasOffset ? " limit ?, ?" : " limit ?" )
+ .toString();
}
- /*
- * Temporary, until MySQL fix Connector/J bug
- */
- /*public String getLimitString(String sql, int offset, int limit) {
- StringBuffer buf = new StringBuffer( sql.length()+20 )
- .append(sql);
- if (offset>0) {
- buf.append(" limit ")
- .append(offset)
- .append(", ")
- .append(limit);
- }
- else {
- buf.append(" limit ")
- .append(limit);
- }
- return buf.toString();
- }*/
-
- /*
- * Temporary, until MySQL fix Connector/J bug
- */
- /*public boolean supportsVariableLimit() {
- return false;
- }*/
-
public char closeQuote() {
return '`';
}
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/PostgreSQLDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -154,9 +154,9 @@
public String getLimitString(String sql, boolean hasOffset) {
return new StringBuffer( sql.length()+20 )
- .append(sql)
- .append(hasOffset ? " limit ? offset ?" : " limit ?")
- .toString();
+ .append( sql )
+ .append( hasOffset ? " limit ? offset ?" : " limit ?" )
+ .toString();
}
public boolean bindLimitParametersInReverseOrder() {
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -292,13 +292,15 @@
}
public String getLimitString(String sql, int offset, int limit) {
- if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries");
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
}
public boolean supportsVariableLimit() {
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -42,12 +42,12 @@
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "sql server has no offset" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( getAfterSelectInsertPoint(querySelect), " top " + limit )
- .toString();
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( getAfterSelectInsertPoint( querySelect ), " top " + limit )
+ .toString();
}
/**
Modified: core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/dialect/TimesTenDialect.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -150,12 +150,12 @@
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "TimesTen does not support offset" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( 6, " first " + limit )
- .toString();
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( 6, " first " + limit )
+ .toString();
}
public boolean supportsCurrentTimestampSelection() {
Modified: core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java 2009-02-04 23:11:46 UTC (rev 15896)
+++ core/branches/Branch_3_2/src/org/hibernate/loader/Loader.java 2009-02-04 23:14:05 UTC (rev 15897)
@@ -1497,6 +1497,10 @@
}
}
+ private int interpretFirstRow(int zeroBasedFirstResult) {
+ return getFactory().getDialect().convertToFirstRowValue( zeroBasedFirstResult );
+ }
+
/**
* Should we pre-process the SQL string, adding a dialect-specific
* LIMIT clause.
@@ -1606,7 +1610,7 @@
* @return The appropriate value to bind into the limit clause.
*/
private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) {
- final int firstRow = getFirstRow( selection );
+ final int firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) );
final int lastRow = selection.getMaxRows().intValue();
if ( dialect.useMaxForLimit() ) {
return lastRow + firstRow;
@@ -1636,7 +1640,7 @@
if ( !hasMaxRows( selection ) ) {
throw new AssertionFailure( "no max results set" );
}
- int firstRow = getFirstRow( selection );
+ int firstRow = interpretFirstRow( getFirstRow( selection ) );
int lastRow = getMaxOrLimit( selection, dialect );
boolean hasFirstRow = dialect.supportsLimitOffset() && ( firstRow > 0 || dialect.forceLimitUsage() );
boolean reverse = dialect.bindLimitParametersInReverseOrder();
@@ -1654,7 +1658,7 @@
final PreparedStatement st,
final RowSelection selection) throws SQLException {
if ( hasMaxRows( selection ) ) {
- st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) );
+ st.setMaxRows( selection.getMaxRows().intValue() + interpretFirstRow( getFirstRow( selection ) ) );
}
}
15 years, 2 months
Hibernate SVN: r15896 - core/branches/Branch_3_2/test/org/hibernate/test/pagination.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-04 18:11:46 -0500 (Wed, 04 Feb 2009)
New Revision: 15896
Modified:
core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.hbm.xml
core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.java
core/branches/Branch_3_2/test/org/hibernate/test/pagination/PaginationTest.java
Log:
HHH-3750 : dialect first-result handling (tests)
Modified: core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.hbm.xml 2009-02-04 23:10:24 UTC (rev 15895)
+++ core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.hbm.xml 2009-02-04 23:11:46 UTC (rev 15896)
@@ -12,7 +12,8 @@
<id name="id">
<generator class="increment"/>
</id>
- <property name="x">
+ <property name="sequence" not-null="true" column="seqval" type="int" />
+ <property name="x">
<column name="xval" not-null="true" precision="20" scale="19" unique-key="xy"/>
</property>
<property name="y">
Modified: core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.java 2009-02-04 23:10:24 UTC (rev 15895)
+++ core/branches/Branch_3_2/test/org/hibernate/test/pagination/DataPoint.java 2009-02-04 23:11:46 UTC (rev 15896)
@@ -8,51 +8,78 @@
*/
public class DataPoint {
private long id;
+ private int sequence;
private BigDecimal x;
private BigDecimal y;
private String description;
+
/**
+ * @return Returns the id.
+ */
+ public long getId() {
+ return id;
+ }
+
+ /**
+ * @param id The id to set.
+ */
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ /**
+ * Getter for property 'sequence'.
+ *
+ * @return Value for property 'sequence'.
+ */
+ public int getSequence() {
+ return sequence;
+ }
+
+ /**
+ * Setter for property 'sequence'.
+ *
+ * @param sequence Value to set for property 'sequence'.
+ */
+ public void setSequence(int sequence) {
+ this.sequence = sequence;
+ }
+
+ /**
* @return Returns the description.
*/
public String getDescription() {
return description;
}
+
/**
* @param description The description to set.
*/
public void setDescription(String description) {
this.description = description;
}
+
/**
- * @return Returns the id.
- */
- public long getId() {
- return id;
- }
- /**
- * @param id The id to set.
- */
- public void setId(long id) {
- this.id = id;
- }
- /**
* @return Returns the x.
*/
public BigDecimal getX() {
return x;
}
+
/**
* @param x The x to set.
*/
public void setX(BigDecimal x) {
this.x = x;
}
+
/**
* @return Returns the y.
*/
public BigDecimal getY() {
return y;
}
+
/**
* @param y The y to set.
*/
Modified: core/branches/Branch_3_2/test/org/hibernate/test/pagination/PaginationTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/pagination/PaginationTest.java 2009-02-04 23:10:24 UTC (rev 15895)
+++ core/branches/Branch_3_2/test/org/hibernate/test/pagination/PaginationTest.java 2009-02-04 23:11:46 UTC (rev 15896)
@@ -2,13 +2,14 @@
package org.hibernate.test.pagination;
import java.math.BigDecimal;
+import java.util.List;
import junit.framework.Test;
import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
+import org.hibernate.SQLQuery;
+import org.hibernate.Query;
+import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -17,7 +18,8 @@
* @author Gavin King
*/
public class PaginationTest extends FunctionalTestCase {
-
+ public static final int ROWS = 100;
+
public PaginationTest(String str) {
super(str);
}
@@ -26,10 +28,6 @@
return new String[] { "pagination/DataPoint.hbm.xml" };
}
- public void configure(Configuration cfg) {
- cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "20");
- }
-
public String getCacheConcurrencyStrategy() {
return null;
}
@@ -37,40 +35,126 @@
public static Test suite() {
return new FunctionalTestClassTestSuite( PaginationTest.class );
}
-
- public void testPagination() {
- Session s = openSession();
- Transaction t = s.beginTransaction();
- for ( int i=0; i<10; i++ ) {
- DataPoint dp = new DataPoint();
- dp.setX( new BigDecimal(i * 0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
- dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
- s.persist(dp);
+
+ public void testLimit() {
+ if ( ! getDialect().supportsLimit() ) {
+ reportSkip( "Dialect does not support limit" );
+ return;
}
- t.commit();
- s.close();
-
- s = openSession();
- t = s.beginTransaction();
- int size = s.createSQLQuery("select id, xval, yval, description from DataPoint order by xval, yval")
- .addEntity(DataPoint.class)
- .setMaxResults(5)
- .list().size();
- assertEquals(size, 5);
- size = s.createQuery("from DataPoint order by x, y")
- .setFirstResult(5)
- .setMaxResults(2)
- .list().size();
- assertEquals(size, 2);
- size = s.createCriteria(DataPoint.class)
- .addOrder( Order.asc("x") )
- .addOrder( Order.asc("y") )
- .setFirstResult(8)
- .list().size();
- assertEquals(size, 2);
- t.commit();
- s.close();
-
+
+ prepareTestData();
+
+ Session session = openSession();
+ session.beginTransaction();
+
+ int count;
+
+ count = generateBaseHQLQuery( session )
+ .setMaxResults( 5 )
+ .list()
+ .size();
+ assertEquals( 5, count );
+
+ count = generateBaseCriteria( session )
+ .setMaxResults( 18 )
+ .list()
+ .size();
+ assertEquals( 18, count );
+
+ count = generateBaseSQLQuery( session )
+ .setMaxResults( 13 )
+ .list()
+ .size();
+ assertEquals( 13, count );
+
+ session.getTransaction().commit();
+ session.close();
+
+ cleanupTestData();
}
+
+ public void testLimitOffset() {
+ if ( ! getDialect().supportsLimitOffset() ) {
+ reportSkip( "Dialect does not support limit+offset" );
+ return;
+ }
+
+ prepareTestData();
+
+ Session session = openSession();
+ session.beginTransaction();
+
+ List result;
+
+ result = generateBaseHQLQuery( session )
+ .setFirstResult( 0 )
+ .setMaxResults( 20 )
+ .list();
+ assertEquals( 20, result.size() );
+ assertEquals( 0, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+ assertEquals( 1, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
+
+ result = generateBaseCriteria( session )
+ .setFirstResult( 1 )
+ .setMaxResults( 20 )
+ .list();
+ assertEquals( 20, result.size() );
+ assertEquals( 1, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+ assertEquals( 2, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
+
+ result = generateBaseCriteria( session )
+ .setFirstResult( 99 )
+ .setMaxResults( Integer.MAX_VALUE )
+ .list();
+ assertEquals( 1, result.size() );
+ assertEquals( 99, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+
+ session.getTransaction().commit();
+ session.close();
+
+ cleanupTestData();
+ }
+
+ private Query generateBaseHQLQuery(Session session) {
+ return session.createQuery( "select dp from DataPoint dp order by dp.sequence" );
+ }
+
+ private Criteria generateBaseCriteria(Session session) {
+ return session.createCriteria( DataPoint.class )
+ .addOrder( Order.asc( "sequence" ) );
+ }
+
+ private SQLQuery generateBaseSQLQuery(Session session) {
+ return session.createSQLQuery( "select id, seqval, xval, yval, description from DataPoint order by seqval" )
+ .addEntity( DataPoint.class );
+ }
+
+ private void prepareTestData() {
+ Session session = openSession();
+ session.beginTransaction();
+ for ( int i = 0; i < ROWS; i++ ) {
+ DataPoint dataPoint = new DataPoint();
+ dataPoint.setSequence( i );
+ dataPoint.setDescription( "data point #" + i );
+ BigDecimal x = new BigDecimal( i * 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN );
+ dataPoint.setX( x );
+ dataPoint.setY( new BigDecimal( Math.cos( x.doubleValue() ) ).setScale( 19, BigDecimal.ROUND_DOWN ) );
+ session.save( dataPoint );
+ }
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ private void cleanupTestData() {
+ Session session = openSession();
+ session.beginTransaction();
+ session.createQuery( "delete DataPoint" ).executeUpdate();
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ private void reportSkip(String message) {
+ reportSkip( message, "pagination support" );
+ }
}
15 years, 2 months
Hibernate SVN: r15895 - in core/branches/Branch_3_3: core/src/main/java/org/hibernate/loader and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-04 18:10:24 -0500 (Wed, 04 Feb 2009)
New Revision: 15895
Modified:
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Dialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/InformixDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/IngresDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
core/branches/Branch_3_3/core/src/main/java/org/hibernate/loader/Loader.java
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java
core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java
Log:
HHH-3750 : dialect first-result handling
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -598,7 +598,7 @@
public String getLimitString(String sql, boolean hasOffset) {
if ( hasOffset ) {
- throw new UnsupportedOperationException( "An offset may not be specified to <TOP n> in Cache SQL" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -48,15 +48,6 @@
return false;
}
- public String getLimitString(String sql, int offset, int limit) {
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
- }
-
public boolean useMaxForLimit() {
return true;
}
@@ -65,4 +56,16 @@
return false;
}
+ public String getLimitString(String sql, int offset, int limit) {
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
+ }
+
}
\ No newline at end of file
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -25,11 +25,11 @@
package org.hibernate.dialect;
/**
-* An SQL dialect for DB2/400
-* @author Peter DeGregorio (pdegregorio)
-* This class provides support for DB2 Universal Database for iSeries,
-* also known as DB2/400.
-*/
+ * An SQL dialect for DB2/400. This class provides support for DB2 Universal Database for iSeries,
+ * also known as DB2/400.
+ *
+ * @author Peter DeGregorio (pdegregorio)
+ */
public class DB2400Dialect extends DB2Dialect {
public boolean supportsSequences() {
@@ -48,15 +48,6 @@
return false;
}
- public String getLimitString(String sql, int offset, int limit) {
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
- }
-
public boolean useMaxForLimit() {
return true;
}
@@ -65,4 +56,16 @@
return false;
}
+ public String getLimitString(String sql, int offset, int limit) {
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
+ }
+
}
\ No newline at end of file
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -247,21 +247,20 @@
}
public String getLimitString(String sql, boolean hasOffset) {
-
int startOfSelect = sql.toLowerCase().indexOf("select");
StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
- .append( sql.substring(0, startOfSelect) ) //add the comment
- .append("select * from ( select ") //nest the main query in an outer select
- .append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list
+ .append( sql.substring(0, startOfSelect) ) // add the comment
+ .append("select * from ( select ") // nest the main query in an outer select
+ .append( getRowNumber(sql) ); // add the rownnumber bit into the outer query select list
if ( hasDistinct(sql) ) {
- pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
- .append( sql.substring(startOfSelect) ) //add the main query
- .append(" ) as row_"); //close off the inner nested select
+ pagingSelect.append(" row_.* from ( ") // add another (inner) nested select
+ .append( sql.substring(startOfSelect) ) // add the main query
+ .append(" ) as row_"); // close off the inner nested select
}
else {
- pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query
+ pagingSelect.append( sql.substring( startOfSelect + 6 ) ); // add the main query
}
pagingSelect.append(" ) as temp_ where rownumber_ ");
@@ -277,6 +276,18 @@
return pagingSelect.toString();
}
+ /**
+ * DB2 does have a one-based offset, however this was actually already handled in the limiot string building
+ * (the '?+1' bit). To not mess up inheritors, I'll leave that part alone and not touch the offset here.
+ *
+ * @param zeroBasedFirstResult The user-supplied, zero-based offset
+ *
+ * @return zeroBasedFirstResult
+ */
+ public int convertToFirstRowValue(int zeroBasedFirstResult) {
+ return zeroBasedFirstResult;
+ }
+
private static boolean hasDistinct(String sql) {
return sql.toLowerCase().indexOf("select distinct")>=0;
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Dialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/Dialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -870,7 +870,26 @@
throw new UnsupportedOperationException( "paged queries not supported" );
}
+ /**
+ * Hibernate APIs explcitly state that setFirstResult() should be a zero-based offset. Here we allow the
+ * Dialect a chance to convert that value based on what the underlying db or driver will expect.
+ * <p/>
+ * NOTE: what gets passed into {@link #getLimitString(String,int,int)} is the zero-based offset. Dialects which
+ * do not {@link #supportsVariableLimit} should take care to perform any needed {@link #convertToFirstRowValue}
+ * calls prior to injecting the limit values into the SQL string.
+ *
+ * @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
+ *
+ * @return The corresponding db/dialect specific offset.
+ *
+ * @see org.hibernate.Query#setFirstResult
+ * @see org.hibernate.Criteria#setFirstResult
+ */
+ public int convertToFirstRowValue(int zeroBasedFirstResult) {
+ return zeroBasedFirstResult;
+ }
+
// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -26,6 +26,7 @@
/**
* An SQL dialect for Firebird.
+ *
* @author Reha CENANI
*/
public class FirebirdDialect extends InterbaseDialect {
@@ -35,10 +36,10 @@
}
public String getLimitString(String sql, boolean hasOffset) {
- return new StringBuffer( sql.length()+20 )
- .append(sql)
- .insert(6, hasOffset ? " first ? skip ?" : " first ?")
- .toString();
+ return new StringBuffer( sql.length() + 20 )
+ .append( sql )
+ .insert( 6, hasOffset ? " first ? skip ?" : " first ?" )
+ .toString();
}
public boolean bindLimitParametersFirst() {
@@ -49,4 +50,4 @@
return true;
}
-}
\ No newline at end of file
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/InformixDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/InformixDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/InformixDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -107,28 +107,27 @@
* @return String
*/
public String getAddForeignKeyConstraintString(
- String constraintName,
- String[] foreignKey,
- String referencedTable,
- String[] primaryKey, boolean referencesPrimaryKey
- ) {
- StringBuffer result = new StringBuffer(30);
-
- result.append(" add constraint ")
- .append(" foreign key (")
- .append( StringHelper.join(", ", foreignKey) )
- .append(") references ")
- .append(referencedTable);
-
- if(!referencesPrimaryKey) {
- result.append(" (")
- .append( StringHelper.join(", ", primaryKey) )
- .append(')');
+ String constraintName,
+ String[] foreignKey,
+ String referencedTable,
+ String[] primaryKey,
+ boolean referencesPrimaryKey) {
+ StringBuffer result = new StringBuffer( 30 )
+ .append( " add constraint " )
+ .append( " foreign key (" )
+ .append( StringHelper.join( ", ", foreignKey ) )
+ .append( ") references " )
+ .append( referencedTable );
+
+ if ( !referencesPrimaryKey ) {
+ result.append( " (" )
+ .append( StringHelper.join( ", ", primaryKey ) )
+ .append( ')' );
}
- result.append(" constraint ").append(constraintName);
-
- return result.toString();
+ result.append( " constraint " ).append( constraintName );
+
+ return result.toString();
}
/**
@@ -172,11 +171,13 @@
}
public String getLimitString(String querySelect, int offset, int limit) {
- if (offset>0) throw new UnsupportedOperationException("informix has no offset");
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
- .toString();
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
+ .toString();
}
public boolean supportsVariableLimit() {
@@ -233,4 +234,4 @@
public String getCurrentTimestampSelectString() {
return "select distinct current timestamp from informix.systables";
}
-}
\ No newline at end of file
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/IngresDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/IngresDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/IngresDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -256,7 +256,7 @@
*/
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "offset not supported" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( querySelect.length() + 16 )
.append( querySelect )
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -236,38 +236,12 @@
}
public String getLimitString(String sql, boolean hasOffset) {
- return new StringBuffer( sql.length()+20 )
- .append(sql)
- .append( hasOffset ? " limit ?, ?" : " limit ?")
- .toString();
+ return new StringBuffer( sql.length() + 20 )
+ .append( sql )
+ .append( hasOffset ? " limit ?, ?" : " limit ?" )
+ .toString();
}
-
- /*
- * Temporary, until MySQL fix Connector/J bug
- */
- /*public String getLimitString(String sql, int offset, int limit) {
- StringBuffer buf = new StringBuffer( sql.length()+20 )
- .append(sql);
- if (offset>0) {
- buf.append(" limit ")
- .append(offset)
- .append(", ")
- .append(limit);
- }
- else {
- buf.append(" limit ")
- .append(limit);
- }
- return buf.toString();
- }*/
- /*
- * Temporary, until MySQL fix Connector/J bug
- */
- /*public boolean supportsVariableLimit() {
- return false;
- }*/
-
public char closeQuote() {
return '`';
}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -180,9 +180,9 @@
public String getLimitString(String sql, boolean hasOffset) {
return new StringBuffer( sql.length()+20 )
- .append(sql)
- .append(hasOffset ? " limit ? offset ?" : " limit ?")
- .toString();
+ .append( sql )
+ .append( hasOffset ? " limit ? offset ?" : " limit ?" )
+ .toString();
}
public boolean bindLimitParametersInReverseOrder() {
@@ -357,4 +357,4 @@
// seems to have spotty LOB suppport
return false;
}
-}
\ No newline at end of file
+}
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -314,13 +314,15 @@
}
public String getLimitString(String sql, int offset, int limit) {
- if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries");
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
}
public boolean supportsVariableLimit() {
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -65,7 +65,7 @@
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "sql server has no offset" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( querySelect.length() + 8 )
.append( querySelect )
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -174,12 +174,12 @@
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "TimesTen does not support offset" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( 6, " first " + limit )
- .toString();
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( 6, " first " + limit )
+ .toString();
}
public boolean supportsCurrentTimestampSelection() {
Modified: core/branches/Branch_3_3/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/branches/Branch_3_3/core/src/main/java/org/hibernate/loader/Loader.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/core/src/main/java/org/hibernate/loader/Loader.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -1521,6 +1521,10 @@
}
}
+ private int interpretFirstRow(int zeroBasedFirstResult) {
+ return getFactory().getDialect().convertToFirstRowValue( zeroBasedFirstResult );
+ }
+
/**
* Should we pre-process the SQL string, adding a dialect-specific
* LIMIT clause.
@@ -1627,7 +1631,7 @@
* @return The appropriate value to bind into the limit clause.
*/
private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) {
- final int firstRow = getFirstRow( selection );
+ final int firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) );
final int lastRow = selection.getMaxRows().intValue();
if ( dialect.useMaxForLimit() ) {
return lastRow + firstRow;
@@ -1657,7 +1661,7 @@
if ( !hasMaxRows( selection ) ) {
throw new AssertionFailure( "no max results set" );
}
- int firstRow = getFirstRow( selection );
+ int firstRow = interpretFirstRow( getFirstRow( selection ) );
int lastRow = getMaxOrLimit( selection, dialect );
boolean hasFirstRow = dialect.supportsLimitOffset() && ( firstRow > 0 || dialect.forceLimitUsage() );
boolean reverse = dialect.bindLimitParametersInReverseOrder();
@@ -1675,7 +1679,7 @@
final PreparedStatement st,
final RowSelection selection) throws SQLException {
if ( hasMaxRows( selection ) ) {
- st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) );
+ st.setMaxRows( selection.getMaxRows().intValue() + interpretFirstRow( getFirstRow( selection ) ) );
}
}
Modified: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml 2009-02-04 23:10:24 UTC (rev 15895)
@@ -1,5 +1,28 @@
<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2009, 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">
@@ -12,7 +35,8 @@
<id name="id">
<generator class="increment"/>
</id>
- <property name="x">
+ <property name="sequence" not-null="true" column="seqval" type="int" />
+ <property name="x">
<column name="xval" not-null="true" precision="20" scale="19" unique-key="xy"/>
</property>
<property name="y">
Modified: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -1,4 +1,26 @@
-//$Id: DataPoint.java 7867 2005-08-11 23:35:33Z oneovthafew $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.pagination;
import java.math.BigDecimal;
@@ -8,51 +30,78 @@
*/
public class DataPoint {
private long id;
+ private int sequence;
private BigDecimal x;
private BigDecimal y;
private String description;
+
/**
+ * @return Returns the id.
+ */
+ public long getId() {
+ return id;
+ }
+
+ /**
+ * @param id The id to set.
+ */
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ /**
+ * Getter for property 'sequence'.
+ *
+ * @return Value for property 'sequence'.
+ */
+ public int getSequence() {
+ return sequence;
+ }
+
+ /**
+ * Setter for property 'sequence'.
+ *
+ * @param sequence Value to set for property 'sequence'.
+ */
+ public void setSequence(int sequence) {
+ this.sequence = sequence;
+ }
+
+ /**
* @return Returns the description.
*/
public String getDescription() {
return description;
}
+
/**
* @param description The description to set.
*/
public void setDescription(String description) {
this.description = description;
}
+
/**
- * @return Returns the id.
- */
- public long getId() {
- return id;
- }
- /**
- * @param id The id to set.
- */
- public void setId(long id) {
- this.id = id;
- }
- /**
* @return Returns the x.
*/
public BigDecimal getX() {
return x;
}
+
/**
* @param x The x to set.
*/
public void setX(BigDecimal x) {
this.x = x;
}
+
/**
* @return Returns the y.
*/
public BigDecimal getY() {
return y;
}
+
/**
* @param y The y to set.
*/
Modified: core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java
===================================================================
--- core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java 2009-02-04 23:05:57 UTC (rev 15894)
+++ core/branches/Branch_3_3/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java 2009-02-04 23:10:24 UTC (rev 15895)
@@ -1,14 +1,37 @@
-//$Id: PaginationTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.pagination;
import java.math.BigDecimal;
+import java.util.List;
import junit.framework.Test;
import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
+import org.hibernate.SQLQuery;
+import org.hibernate.Query;
+import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -17,7 +40,8 @@
* @author Gavin King
*/
public class PaginationTest extends FunctionalTestCase {
-
+ public static final int ROWS = 100;
+
public PaginationTest(String str) {
super(str);
}
@@ -26,10 +50,6 @@
return new String[] { "pagination/DataPoint.hbm.xml" };
}
- public void configure(Configuration cfg) {
- cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "20");
- }
-
public String getCacheConcurrencyStrategy() {
return null;
}
@@ -37,40 +57,126 @@
public static Test suite() {
return new FunctionalTestClassTestSuite( PaginationTest.class );
}
-
- public void testPagination() {
- Session s = openSession();
- Transaction t = s.beginTransaction();
- for ( int i=0; i<10; i++ ) {
- DataPoint dp = new DataPoint();
- dp.setX( new BigDecimal(i * 0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
- dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
- s.persist(dp);
+
+ public void testLimit() {
+ if ( ! getDialect().supportsLimit() ) {
+ reportSkip( "Dialect does not support limit" );
+ return;
}
- t.commit();
- s.close();
-
- s = openSession();
- t = s.beginTransaction();
- int size = s.createSQLQuery("select id, xval, yval, description from DataPoint order by xval, yval")
- .addEntity(DataPoint.class)
- .setMaxResults(5)
- .list().size();
- assertEquals(size, 5);
- size = s.createQuery("from DataPoint order by x, y")
- .setFirstResult(5)
- .setMaxResults(2)
- .list().size();
- assertEquals(size, 2);
- size = s.createCriteria(DataPoint.class)
- .addOrder( Order.asc("x") )
- .addOrder( Order.asc("y") )
- .setFirstResult(8)
- .list().size();
- assertEquals(size, 2);
- t.commit();
- s.close();
-
+
+ prepareTestData();
+
+ Session session = openSession();
+ session.beginTransaction();
+
+ int count;
+
+ count = generateBaseHQLQuery( session )
+ .setMaxResults( 5 )
+ .list()
+ .size();
+ assertEquals( 5, count );
+
+ count = generateBaseCriteria( session )
+ .setMaxResults( 18 )
+ .list()
+ .size();
+ assertEquals( 18, count );
+
+ count = generateBaseSQLQuery( session )
+ .setMaxResults( 13 )
+ .list()
+ .size();
+ assertEquals( 13, count );
+
+ session.getTransaction().commit();
+ session.close();
+
+ cleanupTestData();
}
+
+ public void testLimitOffset() {
+ if ( ! getDialect().supportsLimitOffset() ) {
+ reportSkip( "Dialect does not support limit+offset" );
+ return;
+ }
+
+ prepareTestData();
+
+ Session session = openSession();
+ session.beginTransaction();
+
+ List result;
+
+ result = generateBaseHQLQuery( session )
+ .setFirstResult( 0 )
+ .setMaxResults( 20 )
+ .list();
+ assertEquals( 20, result.size() );
+ assertEquals( 0, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+ assertEquals( 1, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
+
+ result = generateBaseCriteria( session )
+ .setFirstResult( 1 )
+ .setMaxResults( 20 )
+ .list();
+ assertEquals( 20, result.size() );
+ assertEquals( 1, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+ assertEquals( 2, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
+
+ result = generateBaseCriteria( session )
+ .setFirstResult( 99 )
+ .setMaxResults( Integer.MAX_VALUE )
+ .list();
+ assertEquals( 1, result.size() );
+ assertEquals( 99, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+
+ session.getTransaction().commit();
+ session.close();
+
+ cleanupTestData();
+ }
+
+ private Query generateBaseHQLQuery(Session session) {
+ return session.createQuery( "select dp from DataPoint dp order by dp.sequence" );
+ }
+
+ private Criteria generateBaseCriteria(Session session) {
+ return session.createCriteria( DataPoint.class )
+ .addOrder( Order.asc( "sequence" ) );
+ }
+
+ private SQLQuery generateBaseSQLQuery(Session session) {
+ return session.createSQLQuery( "select id, seqval, xval, yval, description from DataPoint order by seqval" )
+ .addEntity( DataPoint.class );
+ }
+
+ private void prepareTestData() {
+ Session session = openSession();
+ session.beginTransaction();
+ for ( int i = 0; i < ROWS; i++ ) {
+ DataPoint dataPoint = new DataPoint();
+ dataPoint.setSequence( i );
+ dataPoint.setDescription( "data point #" + i );
+ BigDecimal x = new BigDecimal( i * 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN );
+ dataPoint.setX( x );
+ dataPoint.setY( new BigDecimal( Math.cos( x.doubleValue() ) ).setScale( 19, BigDecimal.ROUND_DOWN ) );
+ session.save( dataPoint );
+ }
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ private void cleanupTestData() {
+ Session session = openSession();
+ session.beginTransaction();
+ session.createQuery( "delete DataPoint" ).executeUpdate();
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ private void reportSkip(String message) {
+ reportSkip( message, "pagination support" );
+ }
}
15 years, 2 months
Hibernate SVN: r15894 - in core/trunk: core/src/main/java/org/hibernate/loader and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: steve.ebersole(a)jboss.com
Date: 2009-02-04 18:05:57 -0500 (Wed, 04 Feb 2009)
New Revision: 15894
Modified:
core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/InformixDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/IngresDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml
core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java
core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java
Log:
HHH-3750 : dialect first-result handling
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -598,7 +598,7 @@
public String getLimitString(String sql, boolean hasOffset) {
if ( hasOffset ) {
- throw new UnsupportedOperationException( "An offset may not be specified to <TOP n> in Cache SQL" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -48,15 +48,6 @@
return false;
}
- public String getLimitString(String sql, int offset, int limit) {
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
- }
-
public boolean useMaxForLimit() {
return true;
}
@@ -65,4 +56,16 @@
return false;
}
+ public String getLimitString(String sql, int offset, int limit) {
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
+ }
+
}
\ No newline at end of file
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -25,11 +25,11 @@
package org.hibernate.dialect;
/**
-* An SQL dialect for DB2/400
-* @author Peter DeGregorio (pdegregorio)
-* This class provides support for DB2 Universal Database for iSeries,
-* also known as DB2/400.
-*/
+ * An SQL dialect for DB2/400. This class provides support for DB2 Universal Database for iSeries,
+ * also known as DB2/400.
+ *
+ * @author Peter DeGregorio (pdegregorio)
+ */
public class DB2400Dialect extends DB2Dialect {
public boolean supportsSequences() {
@@ -48,15 +48,6 @@
return false;
}
- public String getLimitString(String sql, int offset, int limit) {
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
- }
-
public boolean useMaxForLimit() {
return true;
}
@@ -65,4 +56,16 @@
return false;
}
+ public String getLimitString(String sql, int offset, int limit) {
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
+ }
+
}
\ No newline at end of file
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -247,21 +247,20 @@
}
public String getLimitString(String sql, boolean hasOffset) {
-
int startOfSelect = sql.toLowerCase().indexOf("select");
StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
- .append( sql.substring(0, startOfSelect) ) //add the comment
- .append("select * from ( select ") //nest the main query in an outer select
- .append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list
+ .append( sql.substring(0, startOfSelect) ) // add the comment
+ .append("select * from ( select ") // nest the main query in an outer select
+ .append( getRowNumber(sql) ); // add the rownnumber bit into the outer query select list
if ( hasDistinct(sql) ) {
- pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
- .append( sql.substring(startOfSelect) ) //add the main query
- .append(" ) as row_"); //close off the inner nested select
+ pagingSelect.append(" row_.* from ( ") // add another (inner) nested select
+ .append( sql.substring(startOfSelect) ) // add the main query
+ .append(" ) as row_"); // close off the inner nested select
}
else {
- pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query
+ pagingSelect.append( sql.substring( startOfSelect + 6 ) ); // add the main query
}
pagingSelect.append(" ) as temp_ where rownumber_ ");
@@ -277,6 +276,18 @@
return pagingSelect.toString();
}
+ /**
+ * DB2 does have a one-based offset, however this was actually already handled in the limiot string building
+ * (the '?+1' bit). To not mess up inheritors, I'll leave that part alone and not touch the offset here.
+ *
+ * @param zeroBasedFirstResult The user-supplied, zero-based offset
+ *
+ * @return zeroBasedFirstResult
+ */
+ public int convertToFirstRowValue(int zeroBasedFirstResult) {
+ return zeroBasedFirstResult;
+ }
+
private static boolean hasDistinct(String sql) {
return sql.toLowerCase().indexOf("select distinct")>=0;
}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -870,7 +870,26 @@
throw new UnsupportedOperationException( "paged queries not supported" );
}
+ /**
+ * Hibernate APIs explcitly state that setFirstResult() should be a zero-based offset. Here we allow the
+ * Dialect a chance to convert that value based on what the underlying db or driver will expect.
+ * <p/>
+ * NOTE: what gets passed into {@link #getLimitString(String,int,int)} is the zero-based offset. Dialects which
+ * do not {@link #supportsVariableLimit} should take care to perform any needed {@link #convertToFirstRowValue}
+ * calls prior to injecting the limit values into the SQL string.
+ *
+ * @param zeroBasedFirstResult The user-supplied, zero-based first row offset.
+ *
+ * @return The corresponding db/dialect specific offset.
+ *
+ * @see org.hibernate.Query#setFirstResult
+ * @see org.hibernate.Criteria#setFirstResult
+ */
+ public int convertToFirstRowValue(int zeroBasedFirstResult) {
+ return zeroBasedFirstResult;
+ }
+
// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -26,6 +26,7 @@
/**
* An SQL dialect for Firebird.
+ *
* @author Reha CENANI
*/
public class FirebirdDialect extends InterbaseDialect {
@@ -35,10 +36,10 @@
}
public String getLimitString(String sql, boolean hasOffset) {
- return new StringBuffer( sql.length()+20 )
- .append(sql)
- .insert(6, hasOffset ? " first ? skip ?" : " first ?")
- .toString();
+ return new StringBuffer( sql.length() + 20 )
+ .append( sql )
+ .insert( 6, hasOffset ? " first ? skip ?" : " first ?" )
+ .toString();
}
public boolean bindLimitParametersFirst() {
@@ -49,4 +50,4 @@
return true;
}
-}
\ No newline at end of file
+}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/InformixDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/InformixDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/InformixDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -107,28 +107,27 @@
* @return String
*/
public String getAddForeignKeyConstraintString(
- String constraintName,
- String[] foreignKey,
- String referencedTable,
- String[] primaryKey, boolean referencesPrimaryKey
- ) {
- StringBuffer result = new StringBuffer(30);
-
- result.append(" add constraint ")
- .append(" foreign key (")
- .append( StringHelper.join(", ", foreignKey) )
- .append(") references ")
- .append(referencedTable);
-
- if(!referencesPrimaryKey) {
- result.append(" (")
- .append( StringHelper.join(", ", primaryKey) )
- .append(')');
+ String constraintName,
+ String[] foreignKey,
+ String referencedTable,
+ String[] primaryKey,
+ boolean referencesPrimaryKey) {
+ StringBuffer result = new StringBuffer( 30 )
+ .append( " add constraint " )
+ .append( " foreign key (" )
+ .append( StringHelper.join( ", ", foreignKey ) )
+ .append( ") references " )
+ .append( referencedTable );
+
+ if ( !referencesPrimaryKey ) {
+ result.append( " (" )
+ .append( StringHelper.join( ", ", primaryKey ) )
+ .append( ')' );
}
- result.append(" constraint ").append(constraintName);
-
- return result.toString();
+ result.append( " constraint " ).append( constraintName );
+
+ return result.toString();
}
/**
@@ -172,11 +171,13 @@
}
public String getLimitString(String querySelect, int offset, int limit) {
- if (offset>0) throw new UnsupportedOperationException("informix has no offset");
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
- .toString();
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
+ .toString();
}
public boolean supportsVariableLimit() {
@@ -233,4 +234,4 @@
public String getCurrentTimestampSelectString() {
return "select distinct current timestamp from informix.systables";
}
-}
\ No newline at end of file
+}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/IngresDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/IngresDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/IngresDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -256,7 +256,7 @@
*/
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "offset not supported" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( querySelect.length() + 16 )
.append( querySelect )
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -236,38 +236,12 @@
}
public String getLimitString(String sql, boolean hasOffset) {
- return new StringBuffer( sql.length()+20 )
- .append(sql)
- .append( hasOffset ? " limit ?, ?" : " limit ?")
- .toString();
+ return new StringBuffer( sql.length() + 20 )
+ .append( sql )
+ .append( hasOffset ? " limit ?, ?" : " limit ?" )
+ .toString();
}
-
- /*
- * Temporary, until MySQL fix Connector/J bug
- */
- /*public String getLimitString(String sql, int offset, int limit) {
- StringBuffer buf = new StringBuffer( sql.length()+20 )
- .append(sql);
- if (offset>0) {
- buf.append(" limit ")
- .append(offset)
- .append(", ")
- .append(limit);
- }
- else {
- buf.append(" limit ")
- .append(limit);
- }
- return buf.toString();
- }*/
- /*
- * Temporary, until MySQL fix Connector/J bug
- */
- /*public boolean supportsVariableLimit() {
- return false;
- }*/
-
public char closeQuote() {
return '`';
}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -180,9 +180,9 @@
public String getLimitString(String sql, boolean hasOffset) {
return new StringBuffer( sql.length()+20 )
- .append(sql)
- .append(hasOffset ? " limit ? offset ?" : " limit ?")
- .toString();
+ .append( sql )
+ .append( hasOffset ? " limit ? offset ?" : " limit ?" )
+ .toString();
}
public boolean bindLimitParametersInReverseOrder() {
@@ -357,4 +357,4 @@
// seems to have spotty LOB suppport
return false;
}
-}
\ No newline at end of file
+}
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -314,13 +314,15 @@
}
public String getLimitString(String sql, int offset, int limit) {
- if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries");
- return new StringBuffer(sql.length() + 40)
- .append(sql)
- .append(" fetch first ")
- .append(limit)
- .append(" rows only ")
- .toString();
+ if ( offset > 0 ) {
+ throw new UnsupportedOperationException( "query result offset is not supported" );
+ }
+ return new StringBuffer( sql.length() + 40 )
+ .append( sql )
+ .append( " fetch first " )
+ .append( limit )
+ .append( " rows only " )
+ .toString();
}
public boolean supportsVariableLimit() {
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -65,7 +65,7 @@
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "sql server has no offset" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
return new StringBuffer( querySelect.length() + 8 )
.append( querySelect )
Modified: core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -174,12 +174,12 @@
public String getLimitString(String querySelect, int offset, int limit) {
if ( offset > 0 ) {
- throw new UnsupportedOperationException( "TimesTen does not support offset" );
+ throw new UnsupportedOperationException( "query result offset is not supported" );
}
- return new StringBuffer( querySelect.length()+8 )
- .append(querySelect)
- .insert( 6, " first " + limit )
- .toString();
+ return new StringBuffer( querySelect.length() + 8 )
+ .append( querySelect )
+ .insert( 6, " first " + limit )
+ .toString();
}
public boolean supportsCurrentTimestampSelection() {
Modified: core/trunk/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/Loader.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/core/src/main/java/org/hibernate/loader/Loader.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -1521,6 +1521,10 @@
}
}
+ private int interpretFirstRow(int zeroBasedFirstResult) {
+ return getFactory().getDialect().convertToFirstRowValue( zeroBasedFirstResult );
+ }
+
/**
* Should we pre-process the SQL string, adding a dialect-specific
* LIMIT clause.
@@ -1627,7 +1631,7 @@
* @return The appropriate value to bind into the limit clause.
*/
private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) {
- final int firstRow = getFirstRow( selection );
+ final int firstRow = dialect.convertToFirstRowValue( getFirstRow( selection ) );
final int lastRow = selection.getMaxRows().intValue();
if ( dialect.useMaxForLimit() ) {
return lastRow + firstRow;
@@ -1657,7 +1661,7 @@
if ( !hasMaxRows( selection ) ) {
throw new AssertionFailure( "no max results set" );
}
- int firstRow = getFirstRow( selection );
+ int firstRow = interpretFirstRow( getFirstRow( selection ) );
int lastRow = getMaxOrLimit( selection, dialect );
boolean hasFirstRow = dialect.supportsLimitOffset() && ( firstRow > 0 || dialect.forceLimitUsage() );
boolean reverse = dialect.bindLimitParametersInReverseOrder();
@@ -1675,7 +1679,7 @@
final PreparedStatement st,
final RowSelection selection) throws SQLException {
if ( hasMaxRows( selection ) ) {
- st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) );
+ st.setMaxRows( selection.getMaxRows().intValue() + interpretFirstRow( getFirstRow( selection ) ) );
}
}
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.hbm.xml 2009-02-04 23:05:57 UTC (rev 15894)
@@ -1,5 +1,28 @@
<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2009, 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">
@@ -12,7 +35,8 @@
<id name="id">
<generator class="increment"/>
</id>
- <property name="x">
+ <property name="sequence" not-null="true" column="seqval" type="int" />
+ <property name="x">
<column name="xval" not-null="true" precision="20" scale="19" unique-key="xy"/>
</property>
<property name="y">
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/DataPoint.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -1,4 +1,26 @@
-//$Id: DataPoint.java 7867 2005-08-11 23:35:33Z oneovthafew $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.pagination;
import java.math.BigDecimal;
@@ -8,51 +30,78 @@
*/
public class DataPoint {
private long id;
+ private int sequence;
private BigDecimal x;
private BigDecimal y;
private String description;
+
/**
+ * @return Returns the id.
+ */
+ public long getId() {
+ return id;
+ }
+
+ /**
+ * @param id The id to set.
+ */
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ /**
+ * Getter for property 'sequence'.
+ *
+ * @return Value for property 'sequence'.
+ */
+ public int getSequence() {
+ return sequence;
+ }
+
+ /**
+ * Setter for property 'sequence'.
+ *
+ * @param sequence Value to set for property 'sequence'.
+ */
+ public void setSequence(int sequence) {
+ this.sequence = sequence;
+ }
+
+ /**
* @return Returns the description.
*/
public String getDescription() {
return description;
}
+
/**
* @param description The description to set.
*/
public void setDescription(String description) {
this.description = description;
}
+
/**
- * @return Returns the id.
- */
- public long getId() {
- return id;
- }
- /**
- * @param id The id to set.
- */
- public void setId(long id) {
- this.id = id;
- }
- /**
* @return Returns the x.
*/
public BigDecimal getX() {
return x;
}
+
/**
* @param x The x to set.
*/
public void setX(BigDecimal x) {
this.x = x;
}
+
/**
* @return Returns the y.
*/
public BigDecimal getY() {
return y;
}
+
/**
* @param y The y to set.
*/
Modified: core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java 2009-02-04 18:17:12 UTC (rev 15893)
+++ core/trunk/testsuite/src/test/java/org/hibernate/test/pagination/PaginationTest.java 2009-02-04 23:05:57 UTC (rev 15894)
@@ -1,14 +1,37 @@
-//$Id: PaginationTest.java 10977 2006-12-12 23:28:04Z steve.ebersole(a)jboss.com $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, 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.pagination;
import java.math.BigDecimal;
+import java.util.List;
import junit.framework.Test;
import org.hibernate.Session;
-import org.hibernate.Transaction;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
+import org.hibernate.SQLQuery;
+import org.hibernate.Query;
+import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.junit.functional.FunctionalTestCase;
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
@@ -17,7 +40,8 @@
* @author Gavin King
*/
public class PaginationTest extends FunctionalTestCase {
-
+ public static final int ROWS = 100;
+
public PaginationTest(String str) {
super(str);
}
@@ -26,10 +50,6 @@
return new String[] { "pagination/DataPoint.hbm.xml" };
}
- public void configure(Configuration cfg) {
- cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "20");
- }
-
public String getCacheConcurrencyStrategy() {
return null;
}
@@ -37,40 +57,126 @@
public static Test suite() {
return new FunctionalTestClassTestSuite( PaginationTest.class );
}
-
- public void testPagination() {
- Session s = openSession();
- Transaction t = s.beginTransaction();
- for ( int i=0; i<10; i++ ) {
- DataPoint dp = new DataPoint();
- dp.setX( new BigDecimal(i * 0.1d).setScale(19, BigDecimal.ROUND_DOWN) );
- dp.setY( new BigDecimal( Math.cos( dp.getX().doubleValue() ) ).setScale(19, BigDecimal.ROUND_DOWN) );
- s.persist(dp);
+
+ public void testLimit() {
+ if ( ! getDialect().supportsLimit() ) {
+ reportSkip( "Dialect does not support limit" );
+ return;
}
- t.commit();
- s.close();
-
- s = openSession();
- t = s.beginTransaction();
- int size = s.createSQLQuery("select id, xval, yval, description from DataPoint order by xval, yval")
- .addEntity(DataPoint.class)
- .setMaxResults(5)
- .list().size();
- assertEquals(size, 5);
- size = s.createQuery("from DataPoint order by x, y")
- .setFirstResult(5)
- .setMaxResults(2)
- .list().size();
- assertEquals(size, 2);
- size = s.createCriteria(DataPoint.class)
- .addOrder( Order.asc("x") )
- .addOrder( Order.asc("y") )
- .setFirstResult(8)
- .list().size();
- assertEquals(size, 2);
- t.commit();
- s.close();
-
+
+ prepareTestData();
+
+ Session session = openSession();
+ session.beginTransaction();
+
+ int count;
+
+ count = generateBaseHQLQuery( session )
+ .setMaxResults( 5 )
+ .list()
+ .size();
+ assertEquals( 5, count );
+
+ count = generateBaseCriteria( session )
+ .setMaxResults( 18 )
+ .list()
+ .size();
+ assertEquals( 18, count );
+
+ count = generateBaseSQLQuery( session )
+ .setMaxResults( 13 )
+ .list()
+ .size();
+ assertEquals( 13, count );
+
+ session.getTransaction().commit();
+ session.close();
+
+ cleanupTestData();
}
+
+ public void testLimitOffset() {
+ if ( ! getDialect().supportsLimitOffset() ) {
+ reportSkip( "Dialect does not support limit+offset" );
+ return;
+ }
+
+ prepareTestData();
+
+ Session session = openSession();
+ session.beginTransaction();
+
+ List result;
+
+ result = generateBaseHQLQuery( session )
+ .setFirstResult( 0 )
+ .setMaxResults( 20 )
+ .list();
+ assertEquals( 20, result.size() );
+ assertEquals( 0, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+ assertEquals( 1, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
+
+ result = generateBaseCriteria( session )
+ .setFirstResult( 1 )
+ .setMaxResults( 20 )
+ .list();
+ assertEquals( 20, result.size() );
+ assertEquals( 1, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+ assertEquals( 2, ( ( DataPoint ) result.get( 1 ) ).getSequence() );
+
+ result = generateBaseCriteria( session )
+ .setFirstResult( 99 )
+ .setMaxResults( Integer.MAX_VALUE )
+ .list();
+ assertEquals( 1, result.size() );
+ assertEquals( 99, ( ( DataPoint ) result.get( 0 ) ).getSequence() );
+
+ session.getTransaction().commit();
+ session.close();
+
+ cleanupTestData();
+ }
+
+ private Query generateBaseHQLQuery(Session session) {
+ return session.createQuery( "select dp from DataPoint dp order by dp.sequence" );
+ }
+
+ private Criteria generateBaseCriteria(Session session) {
+ return session.createCriteria( DataPoint.class )
+ .addOrder( Order.asc( "sequence" ) );
+ }
+
+ private SQLQuery generateBaseSQLQuery(Session session) {
+ return session.createSQLQuery( "select id, seqval, xval, yval, description from DataPoint order by seqval" )
+ .addEntity( DataPoint.class );
+ }
+
+ private void prepareTestData() {
+ Session session = openSession();
+ session.beginTransaction();
+ for ( int i = 0; i < ROWS; i++ ) {
+ DataPoint dataPoint = new DataPoint();
+ dataPoint.setSequence( i );
+ dataPoint.setDescription( "data point #" + i );
+ BigDecimal x = new BigDecimal( i * 0.1d ).setScale( 19, BigDecimal.ROUND_DOWN );
+ dataPoint.setX( x );
+ dataPoint.setY( new BigDecimal( Math.cos( x.doubleValue() ) ).setScale( 19, BigDecimal.ROUND_DOWN ) );
+ session.save( dataPoint );
+ }
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ private void cleanupTestData() {
+ Session session = openSession();
+ session.beginTransaction();
+ session.createQuery( "delete DataPoint" ).executeUpdate();
+ session.getTransaction().commit();
+ session.close();
+ }
+
+ private void reportSkip(String message) {
+ reportSkip( message, "pagination support" );
+ }
}
15 years, 2 months
Hibernate SVN: r15893 - validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine.
by hibernate-commits@lists.jboss.org
Author: hardy.ferentschik
Date: 2009-02-04 13:17:12 -0500 (Wed, 04 Feb 2009)
New Revision: 15893
Modified:
validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
Log:
Fixed typo.
Modified: validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java
===================================================================
--- validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java 2009-02-04 18:15:18 UTC (rev 15892)
+++ validator/trunk/hibernate-validator/src/test/java/org/hibernate/validation/engine/ValidatorImplTest.java 2009-02-04 18:17:12 UTC (rev 15893)
@@ -65,7 +65,7 @@
catch ( ValidationException e ) {
assertEquals(
"Wrong error message",
- "Annoated methods must follow the JavaBeans naming convention. age() does not.",
+ "Annotated methods must follow the JavaBeans naming convention. age() does not.",
e.getMessage()
);
}
15 years, 2 months