6 - SQM based on JPA type system

This commit is contained in:
Andrea Boriero 2019-07-18 17:32:17 +01:00
parent 407d46200c
commit 8f63e3176e
11 changed files with 592 additions and 411 deletions

View File

@ -49,33 +49,30 @@ protected void configure(Configuration cfg) {
}
@Override
protected void prepareTest() throws Exception {
Session s = openSession();
s.beginTransaction();
protected void prepareTest() {
inTransaction(
s -> {
Company company1 = new Company( 1 );
s.save( company1 );
Company company1 = new Company( 1 );
s.save( company1 );
User user = new User( 1, company1 );
s.save( user );
User user = new User( 1, company1 );
s.save( user );
Company company2 = new Company( 2 );
s.save( company2 );
s.getTransaction().commit();
s.close();
Company company2 = new Company( 2 );
s.save( company2 );
}
);
}
@Override
protected void cleanupTest() throws Exception {
Session s = openSession();
s.beginTransaction();
protected void cleanupTest() {
inTransaction(
s -> {
s.createQuery( "delete from org.hibernate.test.cache.User" ).executeUpdate();
s.createQuery( "delete from org.hibernate.test.cache.Company" ).executeUpdate();
s.createQuery( "delete from org.hibernate.test.cache.User" ).executeUpdate();
s.createQuery( "delete from org.hibernate.test.cache.Company" ).executeUpdate();
s.getTransaction().commit();
s.close();
}
);
}
/**

View File

@ -39,91 +39,6 @@ public String[] getMappings() {
return new String[] { "cid/Customer.hbm.xml", "cid/Order.hbm.xml", "cid/LineItem.hbm.xml", "cid/Product.hbm.xml" };
}
@Test
public void testNonDistinctCountOfEntityWithCompositeId() {
// the check here is all based on whether we had commas in the expressions inside the count
final HQLQueryPlan plan = sessionFactory().getQueryInterpretationCache().getHQLQueryPlan(
"select count(o) from Order o",
false,
Collections.EMPTY_MAP
);
assertEquals( 1, plan.getTranslators().length );
final QueryTranslator translator = plan.getTranslators()[0];
final String generatedSql = translator.getSQLString();
final int countExpressionListStart = generatedSql.indexOf( "count(" );
final int countExpressionListEnd = generatedSql.indexOf( ")", countExpressionListStart );
final String countExpressionFragment = generatedSql.substring( countExpressionListStart+6, countExpressionListEnd+1 );
final boolean hadCommas = countExpressionFragment.contains( "," );
// set up the expectation based on Dialect...
final boolean expectCommas = sessionFactory().getDialect().supportsTupleCounts();
assertEquals( expectCommas, hadCommas );
}
@Test
@SkipForDialect(value = Oracle8iDialect.class, comment = "Cannot count distinct over multiple columns in Oracle")
@SkipForDialect(value = SQLServerDialect.class, comment = "Cannot count distinct over multiple columns in SQL Server")
public void testDistinctCountOfEntityWithCompositeId() {
// today we do not account for Dialects supportsTupleDistinctCounts() is false. though really the only
// "option" there is to throw an error.
final HQLQueryPlan plan = sessionFactory().getQueryInterpretationCache().getHQLQueryPlan(
"select count(distinct o) from Order o",
false,
Collections.EMPTY_MAP
);
assertEquals( 1, plan.getTranslators().length );
final QueryTranslator translator = plan.getTranslators()[0];
final String generatedSql = translator.getSQLString();
System.out.println( "Generated SQL : " + generatedSql );
final int countExpressionListStart = generatedSql.indexOf( "count(" );
final int countExpressionListEnd = generatedSql.indexOf( ")", countExpressionListStart );
final String countExpressionFragment = generatedSql.substring( countExpressionListStart+6, countExpressionListEnd+1 );
assertTrue( countExpressionFragment.startsWith( "distinct" ) );
assertTrue( countExpressionFragment.contains( "," ) );
Session s = openSession();
s.beginTransaction();
Customer c = new Customer();
c.setCustomerId( "1" );
c.setAddress("123 somewhere");
c.setName("Brett");
Order o1 = new Order( c );
o1.setOrderDate( Calendar.getInstance() );
Order o2 = new Order( c );
o2.setOrderDate( Calendar.getInstance() );
s.persist( c );
s.persist( o1 );
s.persist( o2 );
s.getTransaction().commit();
s.clear();
s.beginTransaction();
try {
long count = ( Long ) s.createQuery( "select count(distinct o) FROM Order o" ).uniqueResult();
if ( ! getDialect().supportsTupleDistinctCounts() ) {
fail( "expected PersistenceException caused by SQLGrammarException" );
}
assertEquals( 2l, count );
}
catch ( PersistenceException e ) {
if ( ! (e.getCause() instanceof SQLGrammarException) || getDialect().supportsTupleDistinctCounts() ) {
throw e;
}
}
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
s.createQuery("delete from Order").executeUpdate();
s.createQuery("delete from Customer").executeUpdate();
s.getTransaction().commit();
s.close();
}
@Test
public void testQuery() {
Session s = openSession();
@ -193,7 +108,7 @@ public void testCompositeIds() {
Object[] stuff = (Object[]) iter.next();
assertTrue(stuff.length==2);
}
iter = s.createQuery("from Order o join o.lineItems li").iterate();
iter = s.createQuery("from Order o join o.lineItems li").list().iterator();
while ( iter.hasNext() ) {
Object[] stuff = (Object[]) iter.next();
assertTrue(stuff.length==2);

View File

@ -6,7 +6,14 @@
*/
package org.hibernate.test.flush;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Root;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals;
import org.hibernate.test.hql.SimpleEntityWithAssociation;
import org.hibernate.testing.TestForIssue;
@ -34,9 +41,20 @@ public void test() {
doInHibernate( this::sessionFactory, session -> {
session.save( e1 );
final Criteria criteria = session.createCriteria( SimpleEntityWithAssociation.class );
criteria.createCriteria( "manyToManyAssociatedEntities" ).add( Restrictions.eq( "name", "e2" ) );
assertEquals( 1, criteria.list().size() );
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<SimpleEntityWithAssociation> criteria = criteriaBuilder.createQuery( SimpleEntityWithAssociation.class );
Root<SimpleEntityWithAssociation> root = criteria.from( SimpleEntityWithAssociation.class );
Join<Object, Object> join = root.join(
"manyToManyAssociatedEntities",
JoinType.INNER
);
criteria.where( criteriaBuilder.equal( join.get( "name" ), "e2" ) );
assertEquals(1, session.createQuery( criteria ).list().size());
// final Criteria criteria = session.createCriteria( SimpleEntityWithAssociation.class );
// criteria.createCriteria( "manyToManyAssociatedEntities" ).add( Restrictions.eq( "name", "e2" ) );
// assertEquals( 1, criteria.list().size() );
} );
}

View File

@ -6,6 +6,8 @@
*/
package org.hibernate.test.interceptor;
import javax.persistence.PersistenceException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
@ -192,25 +194,39 @@ public boolean onSave(Object entity, Serializable id, Object[] state, String[] p
@Test
public void testStatefulIntercept() {
User u = new User( "Gavin", "nivag" );
final StatefulInterceptor statefulInterceptor = new StatefulInterceptor();
Session s = openSession( statefulInterceptor );
statefulInterceptor.setSession(s);
try(Session s = openSession( statefulInterceptor )) {
statefulInterceptor.setSession( s );
Transaction t = s.beginTransaction();
User u = new User("Gavin", "nivag");
s.persist(u);
u.setPassword("vagni");
t.commit();
s.close();
Transaction t = s.beginTransaction();
try {
s.persist( u );
u.setPassword( "vagni" );
t.commit();
}
catch (Exception e) {
if ( t.isActive() ) {
t.rollback();
}
throw e;
}
}
s = openSession();
t = s.beginTransaction();
List logs = s.createCriteria(Log.class).list();
assertEquals( 2, logs.size() );
s.delete(u);
s.createQuery( "delete from Log" ).executeUpdate();
t.commit();
s.close();
inTransaction(
s -> {
CriteriaBuilder criteriaBuilder = s.getCriteriaBuilder();
CriteriaQuery<Log> criteria = criteriaBuilder.createQuery( Log.class );
criteria.from( Log.class );
List<Log> logs = s.createQuery( criteria ).list();
// List logs = s.createCriteria(Log.class).list();
assertEquals( 2, logs.size() );
s.delete(u);
s.createQuery( "delete from Log" ).executeUpdate();
}
);
}
@Test

View File

@ -10,6 +10,8 @@
import java.util.concurrent.CountDownLatch;
import javax.persistence.LockModeType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
@ -79,13 +81,17 @@ public void testLoading() {
@Test
@RequiresDialectFeature( value = DialectChecks.SupportsLockTimeouts.class )
public void testLegacyCriteria() {
public void testCriteria() {
// open a session, begin a transaction and lock row
doInHibernate( this::sessionFactory, session -> {
A it = (A) session.createCriteria( A.class )
.setLockMode( LockMode.PESSIMISTIC_WRITE )
.uniqueResult();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<A> criteria = criteriaBuilder.createQuery( A.class );
criteria.from( A.class );
A it = session.createQuery( criteria ).setLockMode( LockModeType.PESSIMISTIC_WRITE ).uniqueResult();
// A it = (A) session.createCriteria( A.class )
// .setLockMode( LockMode.PESSIMISTIC_WRITE )
// .uniqueResult();
// make sure we got it
assertNotNull( it );
@ -97,12 +103,17 @@ public void testLegacyCriteria() {
@Test
@RequiresDialectFeature( value = DialectChecks.SupportsLockTimeouts.class )
public void testLegacyCriteriaAliasSpecific() {
// open a session, begin a transaction and lock row
public void testCriteriaAliasSpecific() {
// open a session, begin a transaction and lock row
doInHibernate( this::sessionFactory, session -> {
A it = (A) session.createCriteria( A.class )
.setLockMode( "this", LockMode.PESSIMISTIC_WRITE )
.uniqueResult();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<A> criteria = criteriaBuilder.createQuery( A.class );
criteria.from( A.class );
A it = session.createQuery( criteria ).setLockMode("this",LockMode.PESSIMISTIC_WRITE ).uniqueResult();
// A it = (A) session.createCriteria( A.class )
// .setLockMode( "this", LockMode.PESSIMISTIC_WRITE )
// .uniqueResult();
// make sure we got it
assertNotNull( it );

View File

@ -7,11 +7,13 @@
package org.hibernate.test.locking.paging;
import java.util.List;
import javax.persistence.LockModeType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import org.hibernate.LockMode;
import org.hibernate.query.NativeQuery;
import org.hibernate.query.Query;
import org.hibernate.Session;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -26,7 +28,7 @@
*
* @author Steve Ebersole
*/
@TestForIssue( jiraKey = "HHH-1168" )
@TestForIssue(jiraKey = "HHH-1168")
public class PagingAndLockingTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
@ -35,76 +37,82 @@ protected Class<?>[] getAnnotatedClasses() {
@Before
public void createTestData() {
Session session = openSession();
session.beginTransaction();
session.save( new Door( 1, "Front" ) );
session.save( new Door( 2, "Back" ) );
session.save( new Door( 3, "Garage" ) );
session.save( new Door( 4, "French" ) );
session.getTransaction().commit();
session.close();
inTransaction(
session -> {
session.save( new Door( 1, "Front" ) );
session.save( new Door( 2, "Back" ) );
session.save( new Door( 3, "Garage" ) );
session.save( new Door( 4, "French" ) );
}
);
}
@After
public void deleteTestData() {
Session session = openSession();
session.beginTransaction();
session.createQuery( "delete Door" ).executeUpdate();
session.getTransaction().commit();
session.close();
inTransaction(
s -> session.createQuery( "delete Door" ).executeUpdate()
);
}
@Test
public void testHql() {
Session session = openSession();
session.beginTransaction();
Query qry = session.createQuery( "from Door" );
qry.getLockOptions().setLockMode( LockMode.PESSIMISTIC_WRITE );
qry.setFirstResult( 2 );
qry.setMaxResults( 2 );
@SuppressWarnings("unchecked") List<Door> results = qry.list();
assertEquals( 2, results.size() );
for ( Door door : results ) {
assertEquals( LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode( door ) );
}
session.getTransaction().commit();
session.close();
inTransaction(
session -> {
Query qry = session.createQuery( "from Door" );
qry.getLockOptions().setLockMode( LockMode.PESSIMISTIC_WRITE );
qry.setFirstResult( 2 );
qry.setMaxResults( 2 );
@SuppressWarnings("unchecked") List<Door> results = qry.list();
assertEquals( 2, results.size() );
for ( Door door : results ) {
assertEquals( LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode( door ) );
}
}
);
}
@Test
public void testCriteria() {
Session session = openSession();
session.beginTransaction();
Criteria criteria = session.createCriteria( Door.class );
criteria.setLockMode( LockMode.PESSIMISTIC_WRITE );
criteria.setFirstResult( 2 );
criteria.setMaxResults( 2 );
@SuppressWarnings("unchecked") List<Door> results = criteria.list();
assertEquals( 2, results.size() );
for ( Door door : results ) {
assertEquals( LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode( door ) );
}
session.getTransaction().commit();
session.close();
inTransaction(
s -> {
CriteriaBuilder criteriaBuilder = s.getCriteriaBuilder();
CriteriaQuery<Door> criteria = criteriaBuilder.createQuery( Door.class );
criteria.from( Door.class );
// Criteria criteria = session.createCriteria( Door.class );
// criteria.setLockMode( LockMode.PESSIMISTIC_WRITE );
// criteria.setFirstResult( 2 );
// criteria.setMaxResults( 2 );
List<Door> results = s.createQuery( criteria )
.setLockMode( LockModeType.PESSIMISTIC_WRITE )
.setFirstResult( 2 )
.setMaxResults( 2 )
.list();
assertEquals( 2, results.size() );
for ( Door door : results ) {
assertEquals( LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode( door ) );
}
}
);
}
@Test
// @Ignore( "Support for locking on native-sql queries not yet implemented" )
public void testNativeSql() {
Session session = openSession();
session.beginTransaction();
NativeQuery qry = session.createNativeQuery( "select * from door" );
qry.addRoot( "door", Door.class );
qry.getLockOptions().setLockMode( LockMode.PESSIMISTIC_WRITE );
qry.setFirstResult( 2 );
qry.setMaxResults( 2 );
@SuppressWarnings("unchecked") List results = qry.list();
assertEquals( 2, results.size() );
for ( Object door : results ) {
assertEquals( LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode( door ) );
}
session.getTransaction().commit();
session.close();
inTransaction(
session -> {
NativeQuery qry = session.createNativeQuery( "select * from door" );
qry.addRoot( "door", Door.class );
qry.getLockOptions().setLockMode( LockMode.PESSIMISTIC_WRITE );
qry.setFirstResult( 2 );
qry.setMaxResults( 2 );
@SuppressWarnings("unchecked") List results = qry.list();
assertEquals( 2, results.size() );
for ( Object door : results ) {
assertEquals( LockMode.PESSIMISTIC_WRITE, session.getCurrentLockMode( door ) );
}
}
);
}
}

View File

@ -8,6 +8,10 @@
import java.util.Map;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
@ -267,9 +271,7 @@ public void testSaveOrUpdateManaged() {
tx = s.beginTransaction();
assertEquals(
Long.valueOf( 2 ),
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult()
getRowCount( s, NumberedNode.class )
);
s.delete( root );
s.delete( child );
@ -277,7 +279,6 @@ public void testSaveOrUpdateManaged() {
s.close();
}
@Test
public void testSaveOrUpdateGot() {
clearCounts();
@ -306,7 +307,7 @@ public void testSaveOrUpdateGot() {
s = openSession();
tx = s.beginTransaction();
root = ( NumberedNode ) s.get( NumberedNode.class, new Long( root.getId() ) );
root = s.get( NumberedNode.class, new Long( root.getId() ) );
Hibernate.initialize( root.getChildren() );
tx.commit();
s.close();
@ -326,10 +327,8 @@ public void testSaveOrUpdateGot() {
tx = s.beginTransaction();
assertEquals(
s.createCriteria( NumberedNode.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
new Long( 2 ),
getRowCount( s, NumberedNode.class )
);
s.delete( root );
s.delete( child );
@ -363,7 +362,7 @@ public void testSaveOrUpdateGotWithMutableProp() {
s = openSession();
tx = s.beginTransaction();
root = ( Node ) s.get( Node.class, "root" );
root = s.get( Node.class, "root" );
Hibernate.initialize( root.getChildren() );
tx.commit();
s.close();
@ -383,10 +382,8 @@ public void testSaveOrUpdateGotWithMutableProp() {
tx = s.beginTransaction();
assertEquals(
s.createCriteria( Node.class )
.setProjection( Projections.rowCount() )
.uniqueResult(),
new Long( 2 )
new Long( 2 ),
getRowCount(s, Node.class)
);
s.delete( root );
s.delete( child );
@ -506,6 +503,14 @@ public void testSavePersistentEntityWithUpdate() {
s.close();
}
private Long getRowCount(Session s, Class clazz){
CriteriaBuilder criteriaBuilder = s.getCriteriaBuilder();
CriteriaQuery<Long> criteria = criteriaBuilder.createQuery( Long.class );
Root root = criteria.from( clazz );
criteria.select( criteriaBuilder.count( root ) );
return s.createQuery( criteria ).uniqueResult();
}
private void clearCounts() {
sessionFactory().getStatistics().clear();
}

View File

@ -16,18 +16,19 @@
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Root;
import org.hibernate.FetchMode;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.annotations.SortNatural;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
import org.junit.Test;
@ -69,49 +70,59 @@ public void testSortedSetDefinitionInHbmXml() {
@Test
@SuppressWarnings( {"unchecked"})
public void testOrderBy() {
Search s = new Search("Hibernate");
s.getSearchResults().add("jboss.com");
s.getSearchResults().add("hibernate.org");
s.getSearchResults().add("HiA");
Search search = new Search("Hibernate");
search.getSearchResults().add("jboss.com");
search.getSearchResults().add("hibernate.org");
search.getSearchResults().add("HiA");
Session sess = openSession();
Transaction tx = sess.beginTransaction();
sess.persist(s);
sess.flush();
sess.clear();
s = (Search) sess.createCriteria(Search.class).uniqueResult();
assertFalse( Hibernate.isInitialized( s.getSearchResults() ) );
Iterator iter = s.getSearchResults().iterator();
assertEquals( iter.next(), "HiA" );
assertEquals( iter.next(), "hibernate.org" );
assertEquals( iter.next(), "jboss.com" );
assertFalse( iter.hasNext() );
sess.clear();
s = (Search) sess.createCriteria(Search.class)
.setFetchMode("searchResults", FetchMode.JOIN)
.uniqueResult();
assertTrue( Hibernate.isInitialized( s.getSearchResults() ) );
iter = s.getSearchResults().iterator();
assertEquals( iter.next(), "HiA" );
assertEquals( iter.next(), "hibernate.org" );
assertEquals( iter.next(), "jboss.com" );
assertFalse( iter.hasNext() );
sess.clear();
s = (Search) sess.createQuery("from Search s left join fetch s.searchResults")
.uniqueResult();
assertTrue( Hibernate.isInitialized( s.getSearchResults() ) );
iter = s.getSearchResults().iterator();
assertEquals( iter.next(), "HiA" );
assertEquals( iter.next(), "hibernate.org" );
assertEquals( iter.next(), "jboss.com" );
assertFalse( iter.hasNext() );
sess.delete(s);
tx.commit();
sess.close();
inTransaction(
sess -> {
sess.persist(search);
sess.flush();
sess.clear();
CriteriaBuilder criteriaBuilder = sess.getCriteriaBuilder();
CriteriaQuery<Search> criteria = criteriaBuilder.createQuery( Search.class );
criteria.from( Search.class );
Search s = sess.createQuery( criteria ).uniqueResult();
// Search s = (Search) sess.createCriteria(Search.class).uniqueResult();
assertFalse( Hibernate.isInitialized( s.getSearchResults() ) );
Iterator iter = s.getSearchResults().iterator();
assertEquals( iter.next(), "HiA" );
assertEquals( iter.next(), "hibernate.org" );
assertEquals( iter.next(), "jboss.com" );
assertFalse( iter.hasNext() );
sess.clear();
criteria = criteriaBuilder.createQuery( Search.class );
Root<Search> root = criteria.from( Search.class );
root.fetch( "searchResults" , JoinType.LEFT);
s = sess.createQuery( criteria ).uniqueResult();
// s = (Search) sess.createCriteria(Search.class)
// .setFetchMode("searchResults", FetchMode.JOIN)
// .uniqueResult();
assertTrue( Hibernate.isInitialized( s.getSearchResults() ) );
iter = s.getSearchResults().iterator();
assertEquals( iter.next(), "HiA" );
assertEquals( iter.next(), "hibernate.org" );
assertEquals( iter.next(), "jboss.com" );
assertFalse( iter.hasNext() );
sess.clear();
s = (Search) sess.createQuery("from Search s left join fetch s.searchResults")
.uniqueResult();
assertTrue( Hibernate.isInitialized( s.getSearchResults() ) );
iter = s.getSearchResults().iterator();
assertEquals( iter.next(), "HiA" );
assertEquals( iter.next(), "hibernate.org" );
assertEquals( iter.next(), "jboss.com" );
assertFalse( iter.hasNext() );
sess.delete(s);
}
);
}
@Test

View File

@ -114,166 +114,4 @@ else if ( id.equals( 3 ) ) {
session.getTransaction().commit();
session.close();
}
// A warning should be logged if database metadata indicates named parameters are not supported.
@Test
public void testInParametersByName() {
Session session = openSession();
session.beginTransaction();
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 );
query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
ProcedureOutputs procedureResult = query.getOutputs();
Output currentOutput = procedureResult.getCurrent();
assertNotNull( currentOutput );
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
List results = resultSetReturn.getResultList();
assertEquals( 1, results.size() );
Object result = results.get( 0 );
assertTyping( Object[].class, result );
Integer id = (Integer) ( (Object[]) result )[0];
String name = (String) ( (Object[]) result )[1];
assertEquals( 1, (int) id );
assertEquals( "User 1", name );
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersByPosition() {
Session session = openSession();
session.beginTransaction();
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN )
.bindValue( 1 );
query.registerParameter( 2, Integer.class, ParameterMode.IN )
.bindValue( 2 );
ProcedureOutputs procedureResult = query.getOutputs();
Output currentOutput = procedureResult.getCurrent();
assertNotNull( currentOutput );
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
List results = resultSetReturn.getResultList();
assertEquals( 1, results.size() );
Object result = results.get( 0 );
assertTyping( Object[].class, result );
Integer id = (Integer) ( (Object[]) result )[0];
String name = (String) ( (Object[]) result )[1];
assertEquals( 1, (int) id );
assertEquals( "User 1", name );
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersNotSet() {
Session session = openSession();
session.beginTransaction();
// since the procedure does not define defaults for parameters this should result in SQLExceptions on
// execution
{
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN );
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
try {
query.getOutputs();
fail( "Expecting failure due to missing parameter bind" );
}
catch (JDBCException expected) {
}
}
// H2 does not support named parameters
// {
// ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
// query.registerParameter( "start", Integer.class, ParameterMode.IN );
// query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
// try {
// query.getOutputs();
// fail( "Expecting failure due to missing parameter bind" );
// }
// catch (JDBCException expected) {
// }
// }
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersNotSetPass() {
Session session = openSession();
session.beginTransaction();
// unlike #testInParametersNotSet here we are asking that the NULL be passed
// so these executions should succeed
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN ).enablePassingNulls( true );
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
query.getOutputs();
// H2 does not support named parameters
// {
// ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
// query.registerParameter( "start", Integer.class, ParameterMode.IN );
// query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
// try {
// query.getOutputs();
// fail( "Expecting failure due to missing parameter bind" );
// }
// catch (JDBCException expected) {
// }
// }
session.getTransaction().commit();
session.close();
}
@Test
@SuppressWarnings("unchecked")
public void testInParametersNullnessPassingInNamedQueriesViaHints() {
Session session = openSession();
session.beginTransaction();
// similar to #testInParametersNotSet and #testInParametersNotSetPass in terms of testing
// support for specifying whether to pass NULL argument values or not. This version tests
// named procedure support via hints.
// first a fixture - this execution should fail
{
ProcedureCall query = session.getNamedProcedureCall( "findUserRangeNoNullPassing" );
query.getParameterRegistration( 2 ).bindValue( 2 );
try {
query.getOutputs();
fail( "Expecting failure due to missing parameter bind" );
}
catch (JDBCException ignore) {
}
}
// here we enable NULL passing via hint through a named parameter
{
ProcedureCall query = session.getNamedProcedureCall( "findUserRangeNamedNullPassing" );
query.getParameterRegistration( "secondArg" ).bindValue( 2 );
query.getOutputs();
}
// here we enable NULL passing via hint through a named parameter
{
ProcedureCall query = session.getNamedProcedureCall( "findUserRangeOrdinalNullPassing" );
query.getParameterRegistration( 2 ).bindValue( 2 );
query.getOutputs();
}
session.getTransaction().commit();
session.close();
}
}

View File

@ -0,0 +1,120 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.test.cid;
import java.util.Calendar;
import java.util.Collections;
import javax.persistence.PersistenceException;
import org.hibernate.Session;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.exception.SQLGrammarException;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @author Andrea Boriero
*/
public class CompositeIdCountEntityTest extends BaseCoreFunctionalTestCase {
@Override
public String[] getMappings() {
return new String[] { "cid/Customer.hbm.xml", "cid/Order.hbm.xml", "cid/LineItem.hbm.xml", "cid/Product.hbm.xml" };
}
@Test
public void testNonDistinctCountOfEntityWithCompositeId() {
// the check here is all based on whether we had commas in the expressions inside the count
final HQLQueryPlan plan = sessionFactory().getQueryInterpretationCache().getHQLQueryPlan(
"select count(o) from Order o",
false,
Collections.EMPTY_MAP
);
assertEquals( 1, plan.getTranslators().length );
final QueryTranslator translator = plan.getTranslators()[0];
final String generatedSql = translator.getSQLString();
final int countExpressionListStart = generatedSql.indexOf( "count(" );
final int countExpressionListEnd = generatedSql.indexOf( ")", countExpressionListStart );
final String countExpressionFragment = generatedSql.substring( countExpressionListStart+6, countExpressionListEnd+1 );
final boolean hadCommas = countExpressionFragment.contains( "," );
// set up the expectation based on Dialect...
final boolean expectCommas = sessionFactory().getDialect().supportsTupleCounts();
assertEquals( expectCommas, hadCommas );
}
@Test
@SkipForDialect(value = Oracle8iDialect.class, comment = "Cannot count distinct over multiple columns in Oracle")
@SkipForDialect(value = SQLServerDialect.class, comment = "Cannot count distinct over multiple columns in SQL Server")
public void testDistinctCountOfEntityWithCompositeId() {
// today we do not account for Dialects supportsTupleDistinctCounts() is false. though really the only
// "option" there is to throw an error.
final HQLQueryPlan plan = sessionFactory().getQueryInterpretationCache().getHQLQueryPlan(
"select count(distinct o) from Order o",
false,
Collections.EMPTY_MAP
);
assertEquals( 1, plan.getTranslators().length );
final QueryTranslator translator = plan.getTranslators()[0];
final String generatedSql = translator.getSQLString();
System.out.println( "Generated SQL : " + generatedSql );
final int countExpressionListStart = generatedSql.indexOf( "count(" );
final int countExpressionListEnd = generatedSql.indexOf( ")", countExpressionListStart );
final String countExpressionFragment = generatedSql.substring( countExpressionListStart+6, countExpressionListEnd+1 );
assertTrue( countExpressionFragment.startsWith( "distinct" ) );
assertTrue( countExpressionFragment.contains( "," ) );
Session s = openSession();
s.beginTransaction();
Customer c = new Customer();
c.setCustomerId( "1" );
c.setAddress("123 somewhere");
c.setName("Brett");
Order o1 = new Order( c );
o1.setOrderDate( Calendar.getInstance() );
Order o2 = new Order( c );
o2.setOrderDate( Calendar.getInstance() );
s.persist( c );
s.persist( o1 );
s.persist( o2 );
s.getTransaction().commit();
s.clear();
s.beginTransaction();
try {
long count = ( Long ) s.createQuery( "select count(distinct o) FROM Order o" ).uniqueResult();
if ( ! getDialect().supportsTupleDistinctCounts() ) {
fail( "expected PersistenceException caused by SQLGrammarException" );
}
assertEquals( 2l, count );
}
catch ( PersistenceException e ) {
if ( ! (e.getCause() instanceof SQLGrammarException ) || getDialect().supportsTupleDistinctCounts() ) {
throw e;
}
}
s.getTransaction().commit();
s.close();
s = openSession();
s.beginTransaction();
s.createQuery("delete from Order").executeUpdate();
s.createQuery("delete from Customer").executeUpdate();
s.getTransaction().commit();
s.close();
}
}

View File

@ -0,0 +1,242 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.test.sql.storedproc;
import java.util.List;
import javax.persistence.ParameterMode;
import org.hibernate.JDBCException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.procedure.ProcedureCall;
import org.hibernate.procedure.ProcedureOutputs;
import org.hibernate.result.Output;
import org.hibernate.result.ResultSetOutput;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.junit4.ExtraAssertions.assertTyping;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
@RequiresDialect(H2Dialect.class)
public class StoredProcedureParameterRegistrationTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[] { H2ProcTesting.MyEntity.class };
}
@Override
protected void configure(Configuration configuration) {
super.configure( configuration );
H2ProcTesting.applyProcDefinitions( configuration );
}
// A warning should be logged if database metadata indicates named parameters are not supported.
@Test
public void testInParametersByName() {
Session session = openSession();
session.beginTransaction();
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( "start", Integer.class, ParameterMode.IN ).bindValue( 1 );
query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
ProcedureOutputs procedureResult = query.getOutputs();
Output currentOutput = procedureResult.getCurrent();
assertNotNull( currentOutput );
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
List results = resultSetReturn.getResultList();
assertEquals( 1, results.size() );
Object result = results.get( 0 );
assertTyping( Object[].class, result );
Integer id = (Integer) ( (Object[]) result )[0];
String name = (String) ( (Object[]) result )[1];
assertEquals( 1, (int) id );
assertEquals( "User 1", name );
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersByPosition() {
Session session = openSession();
session.beginTransaction();
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN )
.bindValue( 1 );
query.registerParameter( 2, Integer.class, ParameterMode.IN )
.bindValue( 2 );
ProcedureOutputs procedureResult = query.getOutputs();
Output currentOutput = procedureResult.getCurrent();
assertNotNull( currentOutput );
ResultSetOutput resultSetReturn = assertTyping( ResultSetOutput.class, currentOutput );
List results = resultSetReturn.getResultList();
assertEquals( 1, results.size() );
Object result = results.get( 0 );
assertTyping( Object[].class, result );
Integer id = (Integer) ( (Object[]) result )[0];
String name = (String) ( (Object[]) result )[1];
assertEquals( 1, (int) id );
assertEquals( "User 1", name );
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersNotSet() {
Session session = openSession();
session.beginTransaction();
// since the procedure does not define defaults for parameters this should result in SQLExceptions on
// execution
{
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN );
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
try {
query.getOutputs();
fail( "Expecting failure due to missing parameter bind" );
}
catch (JDBCException expected) {
}
}
// H2 does not support named parameters
// {
// ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
// query.registerParameter( "start", Integer.class, ParameterMode.IN );
// query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
// try {
// query.getOutputs();
// fail( "Expecting failure due to missing parameter bind" );
// }
// catch (JDBCException expected) {
// }
// }
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersNotSet() {
Session session = openSession();
session.beginTransaction();
// since the procedure does not define defaults for parameters this should result in SQLExceptions on
// execution
{
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN );
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
try {
query.getOutputs();
fail( "Expecting failure due to missing parameter bind" );
}
catch (JDBCException expected) {
}
}
// H2 does not support named parameters
// {
// ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
// query.registerParameter( "start", Integer.class, ParameterMode.IN );
// query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
// try {
// query.getOutputs();
// fail( "Expecting failure due to missing parameter bind" );
// }
// catch (JDBCException expected) {
// }
// }
session.getTransaction().commit();
session.close();
}
@Test
public void testInParametersNotSetPass() {
Session session = openSession();
session.beginTransaction();
// unlike #testInParametersNotSet here we are asking that the NULL be passed
// so these executions should succeed
ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
query.registerParameter( 1, Integer.class, ParameterMode.IN ).enablePassingNulls( true );
query.registerParameter( 2, Integer.class, ParameterMode.IN ).bindValue( 2 );
query.getOutputs();
// H2 does not support named parameters
// {
// ProcedureCall query = session.createStoredProcedureCall( "findUserRange" );
// query.registerParameter( "start", Integer.class, ParameterMode.IN );
// query.registerParameter( "end", Integer.class, ParameterMode.IN ).bindValue( 2 );
// try {
// query.getOutputs();
// fail( "Expecting failure due to missing parameter bind" );
// }
// catch (JDBCException expected) {
// }
// }
session.getTransaction().commit();
session.close();
}
@Test
@SuppressWarnings("unchecked")
public void testInParametersNullnessPassingInNamedQueriesViaHints() {
Session session = openSession();
session.beginTransaction();
// similar to #testInParametersNotSet and #testInParametersNotSetPass in terms of testing
// support for specifying whether to pass NULL argument values or not. This version tests
// named procedure support via hints.
// first a fixture - this execution should fail
{
ProcedureCall query = session.getNamedProcedureCall( "findUserRangeNoNullPassing" );
query.getParameterRegistration( 2 ).bindValue( 2 );
try {
query.getOutputs();
fail( "Expecting failure due to missing parameter bind" );
}
catch (JDBCException ignore) {
}
}
// here we enable NULL passing via hint through a named parameter
{
ProcedureCall query = session.getNamedProcedureCall( "findUserRangeNamedNullPassing" );
query.getParameterRegistration( "secondArg" ).bindValue( 2 );
query.getOutputs();
}
// here we enable NULL passing via hint through a named parameter
{
ProcedureCall query = session.getNamedProcedureCall( "findUserRangeOrdinalNullPassing" );
query.getParameterRegistration( 2 ).bindValue( 2 );
query.getOutputs();
}
session.getTransaction().commit();
session.close();
}
}