diff --git a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java index b1d94340a9..da50378fc8 100644 --- a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java +++ b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java @@ -40,6 +40,7 @@ import org.hibernate.LockMode; public class NativeSQLQueryCollectionReturn extends NativeSQLQueryNonScalarReturn { private String ownerEntityName; private String ownerProperty; + private final int hashCode; /** * Construct a native-sql return representing a collection initializer @@ -61,6 +62,7 @@ public class NativeSQLQueryCollectionReturn extends NativeSQLQueryNonScalarRetur super( alias, propertyResults, lockMode ); this.ownerEntityName = ownerEntityName; this.ownerProperty = ownerProperty; + this.hashCode = determineHashCode(); } /** @@ -80,4 +82,38 @@ public class NativeSQLQueryCollectionReturn extends NativeSQLQueryNonScalarRetur public String getOwnerProperty() { return ownerProperty; } + + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + if ( !super.equals( o ) ) { + return false; + } + + NativeSQLQueryCollectionReturn that = ( NativeSQLQueryCollectionReturn ) o; + + if ( ownerEntityName != null ? !ownerEntityName.equals( that.ownerEntityName ) : that.ownerEntityName != null ) { + return false; + } + if ( ownerProperty != null ? !ownerProperty.equals( that.ownerProperty ) : that.ownerProperty != null ) { + return false; + } + + return true; + } + + public int hashCode() { + return hashCode; + } + + private int determineHashCode() { + int result = super.hashCode(); + result = 31 * result + ( ownerEntityName != null ? ownerEntityName.hashCode() : 0 ); + result = 31 * result + ( ownerProperty != null ? ownerProperty.hashCode() : 0 ); + return result; + } } diff --git a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java index 6a59e6b8d0..dfa25babe2 100644 --- a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java +++ b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java @@ -37,7 +37,7 @@ import org.hibernate.LockMode; public class NativeSQLQueryJoinReturn extends NativeSQLQueryNonScalarReturn { private String ownerAlias; private String ownerProperty; - + private final int hashCode; /** * Construct a return descriptor representing some form of fetch. * @@ -56,6 +56,7 @@ public class NativeSQLQueryJoinReturn extends NativeSQLQueryNonScalarReturn { super( alias, propertyResults, lockMode ); this.ownerAlias = ownerAlias; this.ownerProperty = ownerProperty; + this.hashCode = determineHashCode(); } /** @@ -76,4 +77,38 @@ public class NativeSQLQueryJoinReturn extends NativeSQLQueryNonScalarReturn { public String getOwnerProperty() { return ownerProperty; } + + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + if ( !super.equals( o ) ) { + return false; + } + + NativeSQLQueryJoinReturn that = ( NativeSQLQueryJoinReturn ) o; + + if ( ownerAlias != null ? !ownerAlias.equals( that.ownerAlias ) : that.ownerAlias != null ) { + return false; + } + if ( ownerProperty != null ? !ownerProperty.equals( that.ownerProperty ) : that.ownerProperty != null ) { + return false; + } + + return true; + } + + public int hashCode() { + return hashCode; + } + + private int determineHashCode() { + int result = super.hashCode(); + result = 31 * result + ( ownerAlias != null ? ownerAlias.hashCode() : 0 ); + result = 31 * result + ( ownerProperty != null ? ownerProperty.hashCode() : 0 ); + return result; + } } diff --git a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java index 2adf31a635..220d2a6784 100644 --- a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java +++ b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java @@ -42,6 +42,7 @@ public abstract class NativeSQLQueryNonScalarReturn implements NativeSQLQueryRet private final String alias; private final LockMode lockMode; private final Map propertyResults = new HashMap(); + private final int hashCode; /** * Constructs some form of non-scalar return descriptor @@ -59,6 +60,7 @@ public abstract class NativeSQLQueryNonScalarReturn implements NativeSQLQueryRet if ( propertyResults != null ) { this.propertyResults.putAll( propertyResults ); } + this.hashCode = determineHashCode(); } /** @@ -87,4 +89,39 @@ public abstract class NativeSQLQueryNonScalarReturn implements NativeSQLQueryRet public Map getPropertyResultsMap() { return Collections.unmodifiableMap( propertyResults ); } + + public int hashCode() { + return hashCode; + } + + private int determineHashCode() { + int result = alias != null ? alias.hashCode() : 0; + result = 31 * result + ( getClass().getName().hashCode() ); + result = 31 * result + ( lockMode != null ? lockMode.hashCode() : 0 ); + result = 31 * result + ( propertyResults != null ? propertyResults.hashCode() : 0 ); + return result; + } + + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + NativeSQLQueryNonScalarReturn that = ( NativeSQLQueryNonScalarReturn ) o; + + if ( alias != null ? !alias.equals( that.alias ) : that.alias != null ) { + return false; + } + if ( lockMode != null ? !lockMode.equals( that.lockMode ) : that.lockMode != null ) { + return false; + } + if ( propertyResults != null ? !propertyResults.equals( that.propertyResults ) : that.propertyResults != null ) { + return false; + } + + return true; + } } diff --git a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java index c70822b073..122fa8119e 100644 --- a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java +++ b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java @@ -37,6 +37,7 @@ import org.hibernate.LockMode; */ public class NativeSQLQueryRootReturn extends NativeSQLQueryNonScalarReturn { private String returnEntityName; + private final int hashCode; /** * Construct a return representing an entity returned at the root @@ -60,7 +61,7 @@ public class NativeSQLQueryRootReturn extends NativeSQLQueryNonScalarReturn { public NativeSQLQueryRootReturn(String alias, String entityName, Map propertyResults, LockMode lockMode) { super( alias, propertyResults, lockMode ); this.returnEntityName = entityName; - + this.hashCode = determineHashCode(); } /** @@ -72,4 +73,33 @@ public class NativeSQLQueryRootReturn extends NativeSQLQueryNonScalarReturn { return returnEntityName; } + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + if ( ! super.equals( o ) ) { + return false; + } + + NativeSQLQueryRootReturn that = ( NativeSQLQueryRootReturn ) o; + + if ( returnEntityName != null ? !returnEntityName.equals( that.returnEntityName ) : that.returnEntityName != null ) { + return false; + } + + return true; + } + + public int hashCode() { + return hashCode; + } + + private int determineHashCode() { + int result = super.hashCode(); + result = 31 * result + ( returnEntityName != null ? returnEntityName.hashCode() : 0 ); + return result; + } } diff --git a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java index 2e1f662507..388196250d 100644 --- a/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java +++ b/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java @@ -34,10 +34,12 @@ import org.hibernate.type.Type; public class NativeSQLQueryScalarReturn implements NativeSQLQueryReturn { private Type type; private String columnAlias; + private final int hashCode; public NativeSQLQueryScalarReturn(String alias, Type type) { this.type = type; this.columnAlias = alias; + this.hashCode = determineHashCode(); } public String getColumnAlias() { @@ -48,4 +50,34 @@ public class NativeSQLQueryScalarReturn implements NativeSQLQueryReturn { return type; } + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + NativeSQLQueryScalarReturn that = ( NativeSQLQueryScalarReturn ) o; + + if ( columnAlias != null ? !columnAlias.equals( that.columnAlias ) : that.columnAlias != null ) { + return false; + } + if ( type != null ? !type.equals( that.type ) : that.type != null ) { + return false; + } + + return true; + } + + public int hashCode() { + return hashCode; + } + + private int determineHashCode() { + int result = type != null ? type.hashCode() : 0; + result = 31 * result + ( getClass().getName().hashCode() ); + result = 31 * result + ( columnAlias != null ? columnAlias.hashCode() : 0 ); + return result; + } } diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/Customer.java b/testsuite/src/test/java/org/hibernate/test/queryplan/Customer.java new file mode 100644 index 0000000000..a3fbaad021 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/Customer.java @@ -0,0 +1,51 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + * + */ +package org.hibernate.test.queryplan; + +/** + * Leaf subclass + * + * @author Steve Ebersole + */ +public class Customer extends User { + private String company; + + protected Customer() { + super(); + } + + public Customer(String name, char sex, String username, String company) { + super( name, sex, username ); + this.company = company; + } + + public String getCompany() { + return company; + } + + public void setCompany(String company) { + this.company = company; + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/Employee.java b/testsuite/src/test/java/org/hibernate/test/queryplan/Employee.java new file mode 100644 index 0000000000..7ca7503ff8 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/Employee.java @@ -0,0 +1,53 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + * + */ +package org.hibernate.test.queryplan; + +import java.util.Date; + +/** + * Leaf subclass + * + * @author Steve Ebersole + */ +public class Employee extends User { + private Date hireDate; + + protected Employee() { + super(); + } + + public Employee(String name, char sex, String username, Date hireDate) { + super( name, sex, username ); + this.hireDate = hireDate; + } + + public Date getHireDate() { + return hireDate; + } + + public void setHireDate(Date hireDate) { + this.hireDate = hireDate; + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/GetHqlQueryPlanTest.java b/testsuite/src/test/java/org/hibernate/test/queryplan/GetHqlQueryPlanTest.java new file mode 100644 index 0000000000..4aec6027a2 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/GetHqlQueryPlanTest.java @@ -0,0 +1,113 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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.queryplan; + +import java.util.Map; + +import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.query.HQLQueryPlan; +import org.hibernate.engine.query.QueryPlanCache; +import org.hibernate.junit.functional.FunctionalTestCase; +import org.hibernate.Session; + +/** + * Tests for HQL query plans + * + * @author Gail Badner + */ +public class GetHqlQueryPlanTest extends FunctionalTestCase { + public GetHqlQueryPlanTest(String string) { + super( string ); + } + + public String[] getMappings() { + return new String[]{ + "queryplan/filter-defs.hbm.xml", + "queryplan/Joined.hbm.xml" + }; + } + + protected Map getEnabledFilters(Session s) { + return ( ( SessionImplementor ) s ).getLoadQueryInfluencers().getEnabledFilters(); + } + + public void testHqlQueryPlan() { + Session s = openSession(); + QueryPlanCache cache = ( ( SessionImplementor ) s ).getFactory().getQueryPlanCache(); + assertTrue( getEnabledFilters( s ).isEmpty() ); + + HQLQueryPlan plan1 = cache.getHQLQueryPlan( "from Person", false, getEnabledFilters( s ) ); + HQLQueryPlan plan2 = cache.getHQLQueryPlan( "from Person where name is null", false, getEnabledFilters( s ) ); + HQLQueryPlan plan3 = cache.getHQLQueryPlan( "from Person where name = :name", false, getEnabledFilters( s ) ); + HQLQueryPlan plan4 = cache.getHQLQueryPlan( "from Person where name = ?", false, getEnabledFilters( s ) ); + + assertNotSame( plan1, plan2 ); + assertNotSame( plan1, plan3 ); + assertNotSame( plan1, plan4 ); + assertNotSame( plan2, plan3 ); + assertNotSame( plan2, plan4 ); + assertNotSame( plan3, plan4 ); + + assertSame( plan1, cache.getHQLQueryPlan( "from Person", false, getEnabledFilters( s ) ) ); + assertSame( plan2, cache.getHQLQueryPlan( "from Person where name is null", false, getEnabledFilters( s ) ) ); + assertSame( plan3, cache.getHQLQueryPlan( "from Person where name = :name", false, getEnabledFilters( s ) ) ); + assertSame( plan4, cache.getHQLQueryPlan( "from Person where name = ?", false, getEnabledFilters( s ) ) ); + + s.close(); + } + + public void testHqlQueryPlanWithEnabledFilter() { + Session s = openSession(); + QueryPlanCache cache = ( ( SessionImplementor ) s ).getFactory().getQueryPlanCache(); + + HQLQueryPlan plan1A = cache.getHQLQueryPlan( "from Person", true, getEnabledFilters( s ) ); + HQLQueryPlan plan1B = cache.getHQLQueryPlan( "from Person", false, getEnabledFilters( s ) ); + + s.enableFilter( "sex" ).setParameter( "sexCode", new Character( 'F' ) ); + HQLQueryPlan plan2A = cache.getHQLQueryPlan( "from Person", true, getEnabledFilters( s ) ); + HQLQueryPlan plan2B = cache.getHQLQueryPlan( "from Person", false, getEnabledFilters( s ) ); + + s.disableFilter( "sex" ); + HQLQueryPlan plan3A = cache.getHQLQueryPlan( "from Person", true, getEnabledFilters( s ) ); + HQLQueryPlan plan3B = cache.getHQLQueryPlan( "from Person", false, getEnabledFilters( s ) ); + + s.enableFilter( "sex" ).setParameter( "sexCode", new Character( 'M' ) ); + HQLQueryPlan plan4A = cache.getHQLQueryPlan( "from Person", true, getEnabledFilters( s ) ); + HQLQueryPlan plan4B = cache.getHQLQueryPlan( "from Person", false, getEnabledFilters( s ) ); + + assertSame( plan1A, plan3A ); + assertSame( plan1B, plan3B ); + assertSame( plan2A, plan4A ); + assertSame( plan2B, plan4B ); + + assertNotSame( plan1A, plan1B ); + assertNotSame( plan1A, plan2A ); + assertNotSame( plan1A, plan2B ); + assertNotSame( plan1B, plan2A ); + assertNotSame( plan1B, plan2B ); + + s.close(); + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/Joined.hbm.xml b/testsuite/src/test/java/org/hibernate/test/queryplan/Joined.hbm.xml new file mode 100644 index 0000000000..e31d041ba7 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/Joined.hbm.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/NativeSQLQueryReturnEqualsAndHashCodeTest.java b/testsuite/src/test/java/org/hibernate/test/queryplan/NativeSQLQueryReturnEqualsAndHashCodeTest.java new file mode 100644 index 0000000000..ad55f78fb3 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/NativeSQLQueryReturnEqualsAndHashCodeTest.java @@ -0,0 +1,277 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, 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.queryplan; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.LockMode; +import org.hibernate.Session; +import org.hibernate.engine.SessionImplementor; +import org.hibernate.engine.query.HQLQueryPlan; +import org.hibernate.engine.query.QueryPlanCache; +import org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn; +import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn; +import org.hibernate.engine.query.sql.NativeSQLQueryReturn; +import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn; +import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn; +import org.hibernate.junit.functional.FunctionalTestCase; +import org.hibernate.type.TypeFactory; + +/** + * Tests equals() and hashCode() for NativeSQLQueryReturn implementations. + * + * @author Gail Badner + */ +public class NativeSQLQueryReturnEqualsAndHashCodeTest extends FunctionalTestCase { + public NativeSQLQueryReturnEqualsAndHashCodeTest(String string) { + super( string ); + } + + public String[] getMappings() { + return new String[] {}; + } + + public void testNativeSQLQueryScalarReturn() { + NativeSQLQueryScalarReturn typeNoAlias = new NativeSQLQueryScalarReturn( null, TypeFactory.basic( "int" ) ); + NativeSQLQueryScalarReturn aliasNoType = new NativeSQLQueryScalarReturn( "abc", null ); + NativeSQLQueryScalarReturn aliasTypeInt = new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( "int" ) ); + NativeSQLQueryScalarReturn aliasTypeLong = new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( "long" ) ); + NativeSQLQueryScalarReturn aliasTypeLongClass = new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( Long.class.getName() ) ); + NativeSQLQueryScalarReturn aliasTypeString = new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( "string" ) ); + NativeSQLQueryScalarReturn aliasTypeStringClass = new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( String.class.getName() ) ); + + check( false, typeNoAlias, aliasNoType ); + check( false, typeNoAlias, aliasTypeInt ); + check( false, typeNoAlias, aliasTypeLong ); + check( false, typeNoAlias, aliasTypeLongClass ); + check( false, typeNoAlias, aliasTypeString ); + check( false, typeNoAlias, aliasTypeStringClass ); + + check( false, aliasNoType, aliasTypeInt ); + check( false, aliasNoType, aliasTypeLong ); + check( false, aliasNoType, aliasTypeLongClass ); + check( false, aliasNoType, aliasTypeString ); + check( false, aliasNoType, aliasTypeStringClass ); + + check( false, aliasTypeInt, aliasTypeLong ); + check( false, aliasTypeInt, aliasTypeLongClass ); + check( false, aliasTypeInt, aliasTypeString ); + check( false, aliasTypeInt, aliasTypeStringClass ); + + check( true, aliasTypeLong, aliasTypeLongClass ); + check( false, aliasTypeLong, aliasTypeString ); + check( false, aliasTypeLong, aliasTypeStringClass ); + + check( false, aliasTypeLongClass, aliasTypeString ); + check( false, aliasTypeLongClass, aliasTypeStringClass ); + + check( true, aliasTypeString, aliasTypeStringClass ); + + check( true, typeNoAlias, new NativeSQLQueryScalarReturn( null, TypeFactory.basic( "int" ) ) ); + check( true, aliasNoType, new NativeSQLQueryScalarReturn( "abc", null ) ); + check( true, aliasTypeInt, new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( "int" ) ) ); + check( true, aliasTypeLong, new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( "long" ) ) ); + check( true, aliasTypeLongClass, new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( Long.class.getName() ) ) ); + check( true, aliasTypeString, new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( "string" ) ) ); + check( true, aliasTypeStringClass, new NativeSQLQueryScalarReturn( "abc", TypeFactory.basic( String.class.getName() ) ) ); + } + + public void testNativeSQLQueryRootReturn() { + NativeSQLQueryRootReturn alias = new NativeSQLQueryRootReturn( "abc", null, null); + NativeSQLQueryRootReturn diffAlias = new NativeSQLQueryRootReturn( "def", null, null); + NativeSQLQueryRootReturn aliasEntityName = new NativeSQLQueryRootReturn( "abc", "Person", null); + NativeSQLQueryRootReturn aliasDiffEntityName = new NativeSQLQueryRootReturn( "abc", "Customer", null); + NativeSQLQueryRootReturn aliasEntityNameLockMode = new NativeSQLQueryRootReturn( "abc", "Person", LockMode.NONE ); + NativeSQLQueryRootReturn aliasEntityNameDiffLockMode = new NativeSQLQueryRootReturn( "abc", "Person", LockMode.OPTIMISTIC ); + + check( false, alias, diffAlias ); + check( false, alias, aliasEntityName ); + check( false, alias, aliasDiffEntityName ); + check( false, alias, aliasEntityNameLockMode ); + check( false, alias, aliasEntityNameDiffLockMode ); + + check( false, diffAlias, aliasEntityName ); + check( false, diffAlias, aliasDiffEntityName ); + check( false, diffAlias, aliasEntityNameLockMode ); + check( false, diffAlias, aliasEntityNameDiffLockMode ); + + check( false, aliasEntityName, aliasDiffEntityName ); + check( false, aliasEntityName, aliasEntityNameLockMode ); + check( false, aliasEntityName, aliasEntityNameDiffLockMode ); + + check( false, aliasDiffEntityName, aliasEntityNameLockMode ); + check( false, aliasDiffEntityName, aliasEntityNameDiffLockMode ); + + check( false, aliasEntityNameLockMode, aliasEntityNameDiffLockMode ); + + check( true, alias, new NativeSQLQueryRootReturn( "abc", null, null) ); + check( true, diffAlias, new NativeSQLQueryRootReturn( "def", null, null) ); + check( true, aliasEntityName, new NativeSQLQueryRootReturn( "abc", "Person", null) ); + check( true, aliasDiffEntityName, new NativeSQLQueryRootReturn( "abc", "Customer", null) ); + check( true, aliasEntityNameLockMode, new NativeSQLQueryRootReturn( "abc", "Person", LockMode.NONE ) ); + check( true, aliasEntityNameDiffLockMode, new NativeSQLQueryRootReturn( "abc", "Person", LockMode.OPTIMISTIC ) ); + } + + public void testNativeSQLQueryJoinReturn() { + NativeSQLQueryJoinReturn r1 = new NativeSQLQueryJoinReturn( "a", "b", "c", null, null); + NativeSQLQueryJoinReturn r2 = new NativeSQLQueryJoinReturn( "a", "c", "b", null, null); + NativeSQLQueryJoinReturn r3NullMap = new NativeSQLQueryJoinReturn( "b", "c", "a", null, null); + NativeSQLQueryJoinReturn r3EmptyMap= new NativeSQLQueryJoinReturn( "b", "c", "a", new HashMap(), null); + NativeSQLQueryJoinReturn r4 = new NativeSQLQueryJoinReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), null); + NativeSQLQueryJoinReturn r5 = new NativeSQLQueryJoinReturn( "b", "c", "a", Collections.singletonMap( "otherkey", "othervalue" ), null); + NativeSQLQueryJoinReturn r6 = new NativeSQLQueryJoinReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), LockMode.NONE ); + NativeSQLQueryJoinReturn r7 = new NativeSQLQueryJoinReturn( "b", "c", "a", null, LockMode.NONE ); + + check( false, r1, r2 ); + check( false, r1, r3NullMap ); + check( false, r1, r3EmptyMap ); + check( false, r1, r4 ); + check( false, r1, r5 ); + check( false, r1, r6 ); + check( false, r1, r7 ); + + check( false, r2, r3NullMap ); + check( false, r2, r3EmptyMap ); + check( false, r2, r4 ); + check( false, r2, r5 ); + check( false, r2, r6 ); + check( false, r2, r7 ); + + check( true, r3NullMap, r3EmptyMap ); + check( false, r3NullMap, r4 ); + check( false, r3NullMap, r5 ); + check( false, r3NullMap, r6 ); + check( false, r3NullMap, r7 ); + + check( false, r3EmptyMap, r4 ); + check( false, r3EmptyMap, r5 ); + check( false, r3EmptyMap, r6 ); + check( false, r3EmptyMap, r7 ); + + check( false, r4, r5 ); + check( false, r4, r6 ); + check( false, r4, r7 ); + + check( false, r5, r6 ); + check( false, r5, r7 ); + + check( false, r6, r7 ); + + check( true, r1, new NativeSQLQueryJoinReturn( "a", "b", "c", null, null) ); + check( true, r2, new NativeSQLQueryJoinReturn( "a", "c", "b", null, null) ); + check( true, r3NullMap, new NativeSQLQueryJoinReturn( "b", "c", "a", null, null) ); + check( true, r3EmptyMap, new NativeSQLQueryJoinReturn( "b", "c", "a", new HashMap(), null) ); + check( true, r4, new NativeSQLQueryJoinReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), null) ); + check( true, r5, new NativeSQLQueryJoinReturn( "b", "c", "a", Collections.singletonMap( "otherkey", "othervalue" ), null) ); + check( true, r6, new NativeSQLQueryJoinReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), LockMode.NONE ) ); + check( true, r7, new NativeSQLQueryJoinReturn( "b", "c", "a", null, LockMode.NONE ) ); + } + + public void testNativeSQLQueryCollectionReturn() { + NativeSQLQueryCollectionReturn r1 = new NativeSQLQueryCollectionReturn( "a", "b", "c", null, null); + NativeSQLQueryCollectionReturn r2 = new NativeSQLQueryCollectionReturn( "a", "c", "b", null, null); + NativeSQLQueryCollectionReturn r3NullMap = new NativeSQLQueryCollectionReturn( "b", "c", "a", null, null); + NativeSQLQueryCollectionReturn r3EmptyMap= new NativeSQLQueryCollectionReturn( "b", "c", "a", new HashMap(), null); + NativeSQLQueryCollectionReturn r4 = new NativeSQLQueryCollectionReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), null); + NativeSQLQueryCollectionReturn r5 = new NativeSQLQueryCollectionReturn( "b", "c", "a", Collections.singletonMap( "otherkey", "othervalue" ), null); + NativeSQLQueryCollectionReturn r6 = new NativeSQLQueryCollectionReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), LockMode.NONE ); + NativeSQLQueryCollectionReturn r7 = new NativeSQLQueryCollectionReturn( "b", "c", "a", null, LockMode.NONE ); + + check( false, r1, r2 ); + check( false, r1, r3NullMap ); + check( false, r1, r3EmptyMap ); + check( false, r1, r4 ); + check( false, r1, r5 ); + check( false, r1, r6 ); + check( false, r1, r7 ); + + check( false, r2, r3NullMap ); + check( false, r2, r3EmptyMap ); + check( false, r2, r4 ); + check( false, r2, r5 ); + check( false, r2, r6 ); + check( false, r2, r7 ); + + check( true, r3NullMap, r3EmptyMap ); + check( false, r3NullMap, r4 ); + check( false, r3NullMap, r5 ); + check( false, r3NullMap, r6 ); + check( false, r3NullMap, r7 ); + + check( false, r3EmptyMap, r4 ); + check( false, r3EmptyMap, r5 ); + check( false, r3EmptyMap, r6 ); + check( false, r3EmptyMap, r7 ); + + check( false, r4, r5 ); + check( false, r4, r6 ); + check( false, r4, r7 ); + + check( false, r5, r6 ); + check( false, r5, r7 ); + + check( false, r6, r7 ); + + check( true, r1, new NativeSQLQueryCollectionReturn( "a", "b", "c", null, null) ); + check( true, r2, new NativeSQLQueryCollectionReturn( "a", "c", "b", null, null) ); + check( true, r3NullMap, new NativeSQLQueryCollectionReturn( "b", "c", "a", null, null) ); + check( true, r3EmptyMap, new NativeSQLQueryCollectionReturn( "b", "c", "a", new HashMap(), null) ); + check( true, r4, new NativeSQLQueryCollectionReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), null) ); + check( true, r5, new NativeSQLQueryCollectionReturn( "b", "c", "a", Collections.singletonMap( "otherkey", "othervalue" ), null) ); + check( true, r6, new NativeSQLQueryCollectionReturn( "b", "c", "a", Collections.singletonMap( "key", "value" ), LockMode.NONE ) ); + check( true, r7, new NativeSQLQueryCollectionReturn( "b", "c", "a", null, LockMode.NONE ) ); + } + + public void testNativeSQLQueryReturnTypes() { + NativeSQLQueryScalarReturn r1 = new NativeSQLQueryScalarReturn( "a", TypeFactory.basic( "int" ) ); + NativeSQLQueryRootReturn r2 = new NativeSQLQueryRootReturn( "a", "b", LockMode.NONE ); + NativeSQLQueryJoinReturn r3 = new NativeSQLQueryJoinReturn( "a", "b", "c", Collections.singletonMap( "key", "value" ), LockMode.NONE ); + NativeSQLQueryCollectionReturn r4 = new NativeSQLQueryCollectionReturn( "a", "b", "c", Collections.singletonMap( "key", "value" ), LockMode.NONE); + + check( false, r1, r2 ); + check( false, r1, r3 ); + check( false, r1, r4 ); + + check( false, r2, r3 ); + check( false, r2, r4 ); + + check( false, r3, r4 ); + } + + private void check(boolean expectedEquals, NativeSQLQueryReturn queryReturn1, NativeSQLQueryReturn queryReturn2) { + if ( expectedEquals ) { + assertTrue( queryReturn1.equals( queryReturn2 ) ); + assertTrue( queryReturn2.equals( queryReturn1 ) ); + assertTrue( queryReturn1.hashCode() == queryReturn2.hashCode() ); + } + else { + assertFalse( queryReturn1.equals( queryReturn2 ) ); + assertFalse( queryReturn2.equals( queryReturn1 ) ); + assertFalse( queryReturn1.hashCode() == queryReturn2.hashCode() ); + } + } +} \ No newline at end of file diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/Person.java b/testsuite/src/test/java/org/hibernate/test/queryplan/Person.java new file mode 100644 index 0000000000..0bfdacbaa5 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/Person.java @@ -0,0 +1,71 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + * + */ +package org.hibernate.test.queryplan; + +/** + * Base of inheritence hierarchy + * + * @author Steve Ebersole + */ +public class Person { + private Long id; + private String name; + private char sex; + + /** + * Used by persistence + */ + protected Person() { + } + + public Person(String name, char sex) { + this.name = name; + this.sex = sex; + } + + public Long getId() { + return id; + } + + private void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public char getSex() { + return sex; + } + + public void setSex(char sex) { + this.sex = sex; + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/User.java b/testsuite/src/test/java/org/hibernate/test/queryplan/User.java new file mode 100644 index 0000000000..bb9444cec3 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/User.java @@ -0,0 +1,51 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + * + */ +package org.hibernate.test.queryplan; + +/** + * Non-leaf subclass + * + * @author Steve Ebersole + */ +public class User extends Person { + private String username; + + protected User() { + super(); + } + + public User(String name, char sex, String username) { + super( name, sex ); + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } +} diff --git a/testsuite/src/test/java/org/hibernate/test/queryplan/filter-defs.hbm.xml b/testsuite/src/test/java/org/hibernate/test/queryplan/filter-defs.hbm.xml new file mode 100644 index 0000000000..130edee8a8 --- /dev/null +++ b/testsuite/src/test/java/org/hibernate/test/queryplan/filter-defs.hbm.xml @@ -0,0 +1,35 @@ + + + + + + + + + + \ No newline at end of file