[hibernate-commits] Hibernate SVN: r18931 - in core/trunk/entitymanager/src: test/java/org/hibernate/ejb/test and 1 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Mar 5 17:22:06 EST 2010


Author: smarlow at redhat.com
Date: 2010-03-05 17:22:05 -0500 (Fri, 05 Mar 2010)
New Revision: 18931

Modified:
   core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
   core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
   core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java
Log:
HHH-4972 javax.persistence.query.timeout and javax.persistence.lock.timeout can be passed when creating an EMF

Modified: core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java
===================================================================
--- core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java	2010-03-05 18:17:36 UTC (rev 18930)
+++ core/trunk/entitymanager/src/main/java/org/hibernate/ejb/AbstractEntityManagerImpl.java	2010-03-05 22:22:05 UTC (rev 18931)
@@ -118,6 +118,7 @@
 		entityManagerSpecificProperties.add( AvailableSettings.FLUSH_MODE );
 		entityManagerSpecificProperties.add( AvailableSettings.SHARED_CACHE_RETRIEVE_MODE );
 		entityManagerSpecificProperties.add( AvailableSettings.SHARED_CACHE_STORE_MODE );
+		entityManagerSpecificProperties.add( QueryHints.SPEC_HINT_TIMEOUT );
 	}
 
 	private EntityManagerFactoryImpl entityManagerFactory;
@@ -168,6 +169,17 @@
 		);
 	}
 
+	private Query applyProperties(Query query) {
+		if ( lockOptions.getLockMode() != LockMode.NONE ) {
+			query.setLockMode( getLockMode(lockOptions.getLockMode()));
+		}
+		Object queryTimeout;
+		if ( (queryTimeout = getProperties().get(QueryHints.SPEC_HINT_TIMEOUT)) != null ) {
+			query.setHint ( QueryHints.SPEC_HINT_TIMEOUT, queryTimeout );
+		}
+		return query;
+	}
+
 	private CacheRetrieveMode currentCacheRetrieveMode() {
 		return determineCacheRetrieveMode( properties );
 	}
@@ -248,7 +260,7 @@
 
 	public Query createQuery(String jpaqlString) {
 		try {
-			return new QueryImpl<Object>( getSession().createQuery( jpaqlString ), this );
+			return applyProperties( new QueryImpl<Object>( getSession().createQuery( jpaqlString ), this ) );
 		}
 		catch ( HibernateException he ) {
 			throw convert( he );

Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java	2010-03-05 18:17:36 UTC (rev 18930)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/TestCase.java	2010-03-05 22:22:05 UTC (rev 18931)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
 /*
  * Hibernate, Relational Persistence for Idiomatic Java
  *
@@ -134,6 +134,12 @@
 		return isolatedEm;
 	}
 
+	protected EntityManager createIsolatedEntityManager(Map props) {
+		EntityManager isolatedEm = factory.createEntityManager(props);
+		isolatedEms.add( isolatedEm );
+		return isolatedEm;
+	}
+
 	/**
 	 * always reopen a new EM and clse the existing one
 	 */

Modified: core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java
===================================================================
--- core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java	2010-03-05 18:17:36 UTC (rev 18930)
+++ core/trunk/entitymanager/src/test/java/org/hibernate/ejb/test/lock/LockTest.java	2010-03-05 22:22:05 UTC (rev 18931)
@@ -601,7 +601,96 @@
 		}
 	}
 
+	public void testQueryTimeoutEMProps() throws Exception {
+		// TODO:  replace dialect instanceof test with a Dialect.hasCapability
+		if ( ! (getDialect() instanceof Oracle10gDialect)) {
+			log.info("skipping testQueryTimeout");
+			return;
+ 		}
+		EntityManager em = getOrCreateEntityManager();
+		Map queryTimeoutProps = new HashMap();
+		queryTimeoutProps.put("javax.persistence.query.timeout", new Integer(500) ); // 1 sec timeout (should round up)
+		final EntityManager em2 = createIsolatedEntityManager(queryTimeoutProps);
+		Lock lock = new Lock();
+		Thread t = null;
+		FutureTask<Boolean> bgTask = null;
+		final CountDownLatch latch = new CountDownLatch(1);
+		try {
+			lock.setName( "testQueryTimeout" );
 
+			em.getTransaction().begin();
+			em.persist( lock );
+			em.getTransaction().commit();
+			em.clear();
+
+			em.getTransaction().begin();
+			lock = em.getReference( Lock.class, lock.getId() );
+			em.lock( lock, LockModeType.PESSIMISTIC_WRITE );
+			final Integer id = lock.getId();
+			lock.getName();		// force entity to be read
+			log.info("testQueryTimeout: got write lock");
+
+			bgTask = new FutureTask<Boolean>( new Callable() {
+				public Boolean call() {
+					try {
+						boolean timedOut = false;	// true (success) if LockTimeoutException occurred
+						em2.getTransaction().begin();
+						log.info( "testQueryTimeout: (BG) about to read write-locked entity" );
+						// we should block on the following read
+						Lock lock2 = em2.getReference( Lock.class, id );
+						lock2.getName();		//  force entity to be read
+						log.info( "testQueryTimeout: (BG) read write-locked entity" );
+						try {
+							// we should block on the following read
+							Query query = em2.createQuery(
+									  "select L from Lock_ L where L.id < 10000 ");
+							query.setLockMode( LockModeType.PESSIMISTIC_READ );
+							List<Lock> resultList = query.getResultList();
+							String name = resultList.get(0).getName(); //  force entity to be read
+							log.info( "testQueryTimeout: name read =" + name );
+						}
+						catch( QueryTimeoutException e) {
+							// success
+							log.info( "testQueryTimeout: (BG) got expected timeout exception" );
+							 timedOut = true;
+						}
+						catch ( Throwable e) {
+							log.info( "testQueryTimeout: Expected LockTimeoutException but got unexpected exception", e );
+						}
+						em2.getTransaction().commit();
+						return new Boolean( timedOut );
+					}
+					finally {
+						latch.countDown();	// signal that we finished
+					}
+				}
+			} );
+			t = new Thread(bgTask);
+			t.setDaemon( true );
+			t.setName( "testQueryTimeout (bg)" );
+			t.start();
+			boolean latchSet = latch.await( 10, TimeUnit.SECONDS );  // should return quickly on success
+			assertTrue( "background test thread finished (lock timeout is broken)", latchSet);
+			assertTrue( "background test thread timed out on lock attempt", bgTask.get().booleanValue() );
+			em.getTransaction().commit();
+		}
+		finally {
+			if ( em.getTransaction().isActive() ) {
+				em.getTransaction().rollback();
+			}
+			if ( t != null) {	  // wait for background thread to finish before deleting entity
+				t.join();
+			}
+			em.getTransaction().begin();
+			lock = em.getReference( Lock.class, lock.getId() );
+			em.remove( lock );
+			em.getTransaction().commit();
+			em.close();
+			em2.close();
+		}
+	}
+
+
 	public Class[] getAnnotatedClasses() {
 		return new Class[]{
 				Lock.class,



More information about the hibernate-commits mailing list