[hibernate-commits] Hibernate SVN: r15894 - in core/trunk: core/src/main/java/org/hibernate/loader and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Feb 4 18:05:58 EST 2009


Author: steve.ebersole at 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 at 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" );
+	}
 }
 




More information about the hibernate-commits mailing list