* now a transaction is marked for rollback for all RuntimeExceptions not only the CosntraintViolationExcpetion.
* Also updated FlushAndTransactionTest which had invalid assertions.


git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18850 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Hardy Ferentschik 2010-02-22 21:17:12 +00:00
parent b15adba4ef
commit f3aa0c63bb
5 changed files with 213 additions and 124 deletions

View File

@ -63,7 +63,6 @@ import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -112,6 +111,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
private static final Logger log = LoggerFactory.getLogger( AbstractEntityManagerImpl.class );
private static final List<String> entityManagerSpecificProperties = new ArrayList<String>();
static {
entityManagerSpecificProperties.add( AvailableSettings.LOCK_SCOPE );
entityManagerSpecificProperties.add( AvailableSettings.LOCK_TIMEOUT );
@ -136,9 +136,9 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
this.persistenceContextType = type;
this.transactionType = transactionType;
this.lockOptions = new LockOptions( );
this.lockOptions = new LockOptions();
this.properties = new HashMap<String, Object>();
if(properties != null) {
if ( properties != null ) {
for ( String key : entityManagerSpecificProperties ) {
if ( properties.containsKey( key ) ) {
this.properties.put( key, properties.get( key ) );
@ -159,7 +159,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
private void applyProperties() {
getSession().setFlushMode( ConfigurationHelper.getFlushMode( properties.get( AvailableSettings.FLUSH_MODE ) ) );
setLockOptions(this.properties, this.lockOptions);
setLockOptions( this.properties, this.lockOptions );
getSession().setCacheMode(
CacheModeHelper.interpretCacheMode(
currentCacheStoreMode(),
@ -172,16 +172,16 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
return determineCacheRetrieveMode( properties );
}
private CacheRetrieveMode determineCacheRetrieveMode(Map<String,Object> settings) {
return (CacheRetrieveMode) settings.get( AvailableSettings.SHARED_CACHE_RETRIEVE_MODE );
private CacheRetrieveMode determineCacheRetrieveMode(Map<String, Object> settings) {
return ( CacheRetrieveMode ) settings.get( AvailableSettings.SHARED_CACHE_RETRIEVE_MODE );
}
private CacheStoreMode currentCacheStoreMode() {
return determineCacheStoreMode( properties );
}
private CacheStoreMode determineCacheStoreMode(Map<String,Object> settings) {
return (CacheStoreMode) properties.get( AvailableSettings.SHARED_CACHE_STORE_MODE );
private CacheStoreMode determineCacheStoreMode(Map<String, Object> settings) {
return ( CacheStoreMode ) properties.get( AvailableSettings.SHARED_CACHE_STORE_MODE );
}
private void setLockOptions(Map<String, Object> props, LockOptions options) {
@ -229,19 +229,19 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
* set.
*/
private void setDefaultProperties() {
if ( properties.get( AvailableSettings.FLUSH_MODE ) == null) {
if ( properties.get( AvailableSettings.FLUSH_MODE ) == null ) {
properties.put( AvailableSettings.FLUSH_MODE, getSession().getFlushMode().toString() );
}
if ( properties.get( AvailableSettings.LOCK_SCOPE ) == null) {
if ( properties.get( AvailableSettings.LOCK_SCOPE ) == null ) {
this.properties.put( AvailableSettings.LOCK_SCOPE, PessimisticLockScope.EXTENDED.name() );
}
if ( properties.get( AvailableSettings.LOCK_TIMEOUT ) == null) {
if ( properties.get( AvailableSettings.LOCK_TIMEOUT ) == null ) {
properties.put( AvailableSettings.LOCK_TIMEOUT, LockOptions.WAIT_FOREVER );
}
if ( properties.get( AvailableSettings.SHARED_CACHE_RETRIEVE_MODE ) == null) {
if ( properties.get( AvailableSettings.SHARED_CACHE_RETRIEVE_MODE ) == null ) {
properties.put( AvailableSettings.SHARED_CACHE_RETRIEVE_MODE, CacheModeHelper.DEFAULT_RETRIEVE_MODE );
}
if ( properties.get( AvailableSettings.SHARED_CACHE_STORE_MODE ) == null) {
if ( properties.get( AvailableSettings.SHARED_CACHE_STORE_MODE ) == null ) {
properties.put( AvailableSettings.SHARED_CACHE_STORE_MODE, CacheModeHelper.DEFAULT_STORE_MODE );
}
}
@ -261,7 +261,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
if ( hqlQuery.getReturnTypes().length != 1 ) {
throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return" );
}
if ( ! resultClass.isAssignableFrom( hqlQuery.getReturnTypes()[0].getReturnedClass() ) ) {
if ( !resultClass.isAssignableFrom( hqlQuery.getReturnTypes()[0].getReturnedClass() ) ) {
throw new IllegalArgumentException(
"Type specified for TypedQuery [" +
resultClass.getName() +
@ -290,7 +290,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
// determine if we need a result transformer
List tupleElements = Tuple.class.equals( resultClass )
? ( (CompoundSelectionImpl<Tuple>) selection ).getCompoundSelectionItems()
? ( ( CompoundSelectionImpl<Tuple> ) selection ).getCompoundSelectionItems()
: null;
if ( options.getValueHandlers() != null || tupleElements != null ) {
hqlQuery.setResultTransformer(
@ -321,7 +321,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
valueHandlerResult = tuple;
}
else {
valueHandlerResult = new Object[ tuple.length ];
valueHandlerResult = new Object[tuple.length];
for ( int i = 0; i < tuple.length; i++ ) {
ValueHandlerFactory.ValueHandler valueHandler = valueHandlers.get( i );
valueHandlerResult[i] = valueHandler == null
@ -352,10 +352,12 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
public <X> X get(TupleElement<X> tupleElement) {
int index = tupleElements.indexOf( tupleElement );
if ( index < 0 ) {
throw new IllegalArgumentException( "Requested tuple element did not correspond to element in the result tuple" );
throw new IllegalArgumentException(
"Requested tuple element did not correspond to element in the result tuple"
);
}
// index should be "in range" by nature of size check in ctor
return (X) tuples[index];
return ( X ) tuples[index];
}
public Object get(String alias) {
@ -364,7 +366,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
alias = alias.trim();
if ( alias.length() > 0 ) {
int i = 0;
for ( TupleElement selection : (List<TupleElement>) tupleElements ) {
for ( TupleElement selection : ( List<TupleElement> ) tupleElements ) {
if ( alias.equals( selection.getAlias() ) ) {
index = i;
break;
@ -383,7 +385,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
public <X> X get(String alias, Class<X> type) {
return (X) get( alias );
return ( X ) get( alias );
}
public Object get(int i) {
@ -396,7 +398,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
public <X> X get(int i, Class<X> type) {
return (X) get( i );
return ( X ) get( i );
}
public Object[] toArray() {
@ -404,7 +406,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
public List<TupleElement<?>> getElements() {
return (List<TupleElement<?>>) tupleElements;
return ( List<TupleElement<?>> ) tupleElements;
}
}
}
@ -440,7 +442,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
if ( namedQuery.getReturnTypes().length != 1 ) {
throw new IllegalArgumentException( "Cannot create TypedQuery for query with more than one return" );
}
if ( ! resultClass.isAssignableFrom( namedQuery.getReturnTypes()[0].getReturnedClass() ) ) {
if ( !resultClass.isAssignableFrom( namedQuery.getReturnTypes()[0].getReturnedClass() ) ) {
throw new IllegalArgumentException(
"Type specified for TypedQuery [" +
resultClass.getName() +
@ -512,19 +514,19 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
@SuppressWarnings("unchecked")
public <A> A find(Class<A> entityClass, Object primaryKey) {
return find( entityClass, primaryKey, null, null);
return find( entityClass, primaryKey, null, null );
}
public <T> T find(Class<T> entityClass, Object primaryKey, Map<String, Object> properties) {
return find(entityClass, primaryKey, null, null);
return find( entityClass, primaryKey, null, null );
}
@SuppressWarnings("unchecked")
public <A> A find(Class<A> entityClass, Object primaryKey, LockModeType lockModeType) {
return find(entityClass, primaryKey, lockModeType, null);
public <A> A find(Class<A> entityClass, Object primaryKey, LockModeType lockModeType) {
return find( entityClass, primaryKey, lockModeType, null );
}
public <A> A find(Class<A> entityClass, Object primaryKey, LockModeType lockModeType, Map<String, Object> properties) {
public <A> A find(Class<A> entityClass, Object primaryKey, LockModeType lockModeType, Map<String, Object> properties) {
CacheMode previousCacheMode = getSession().getCacheMode();
CacheMode cacheMode = determineAppropriateLocalCacheMode( properties );
LockOptions lockOptions = null;
@ -536,8 +538,9 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
getLockRequest( lockModeType, properties )
);
}
else
else {
return ( A ) getSession().get( entityClass, ( Serializable ) primaryKey );
}
}
catch ( ObjectDeletedException e ) {
//the spec is silent about people doing remove() find() on the same PC
@ -557,7 +560,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
throw new IllegalArgumentException( e.getMessage(), e );
}
catch ( HibernateException he ) {
throw convert( he , lockOptions );
throw convert( he, lockOptions );
}
finally {
getSession().setCacheMode( previousCacheMode );
@ -635,15 +638,15 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
public void refresh(Object entity) {
refresh(entity, null, null);
refresh( entity, null, null );
}
public void refresh(Object entity, Map<String, Object> properties) {
refresh(entity, null, null);
refresh( entity, null, null );
}
public void refresh(Object entity, LockModeType lockModeType) {
refresh(entity, lockModeType, null);
refresh( entity, lockModeType, null );
}
public void refresh(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
@ -656,16 +659,18 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
if ( !getSession().contains( entity ) ) {
throw new IllegalArgumentException( "Entity not managed" );
}
if(lockModeType != null)
getSession().refresh( entity, (lockOptions = getLockRequest(lockModeType, properties) ) );
else
if ( lockModeType != null ) {
getSession().refresh( entity, ( lockOptions = getLockRequest( lockModeType, properties ) ) );
}
else {
getSession().refresh( entity );
}
}
catch ( MappingException e ) {
throw new IllegalArgumentException( e.getMessage(), e );
}
catch ( HibernateException he ) {
throw convert( he, lockOptions);
throw convert( he, lockOptions );
}
finally {
getSession().setCacheMode( previousCacheMode );
@ -693,7 +698,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
if ( !contains( entity ) ) {
throw new IllegalArgumentException( "entity not in the persistence context" );
}
return getLockModeType(getSession().getCurrentLockMode(entity));
return getLockModeType( getSession().getCurrentLockMode( entity ) );
}
public void setProperty(String s, Object o) {
@ -822,7 +827,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
public void lock(Object entity, LockModeType lockMode) {
lock( entity, lockMode, null);
lock( entity, lockMode, null );
}
public void lock(Object entity, LockModeType lockModeType, Map<String, Object> properties) {
@ -834,10 +839,11 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
if ( !contains( entity ) ) {
throw new IllegalArgumentException( "entity not in the persistence context" );
}
getSession().buildLockRequest( (lockOptions = getLockRequest(lockModeType, properties))).lock( entity );
getSession().buildLockRequest( ( lockOptions = getLockRequest( lockModeType, properties ) ) )
.lock( entity );
}
catch ( HibernateException he ) {
throw convert( he , lockOptions);
throw convert( he, lockOptions );
}
}
@ -903,9 +909,9 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
return ( T ) getSession();
}
if ( EntityManager.class.isAssignableFrom( clazz ) ) {
return (T) this;
return ( T ) this;
}
throw new PersistenceException( "Hibernate cannot unwrap " + clazz);
throw new PersistenceException( "Hibernate cannot unwrap " + clazz );
}
private void joinTransaction(boolean ignoreNotJoining) {
@ -989,7 +995,7 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
catch ( HibernateException he ) {
throw convert( he );
}
catch( PersistenceException pe ) {
catch ( PersistenceException pe ) {
handlePersistenceException( pe );
throw pe;
}
@ -1091,21 +1097,17 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
*/
//FIXME should we remove all calls to this method and use convert(RuntimeException) ?
public RuntimeException convert(HibernateException e) {
return convert(e, null);
return convert( e, null );
}
/**
* {@inheritDoc}
*/
public RuntimeException convert(RuntimeException e) {
RuntimeException result = e;
if ( e instanceof HibernateException ) {
result = convert( (HibernateException) e );
result = convert( ( HibernateException ) e );
}
else if (e instanceof ConstraintViolationException) {
else {
markAsRollback();
}
//if any RT exception should mark the tx for rollback, convert the last else if into a else
return result;
}
@ -1119,12 +1121,12 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
return converted;
}
else if ( e instanceof org.hibernate.OptimisticLockException ) {
PersistenceException converted = wrapLockException(e, lockOptions);
PersistenceException converted = wrapLockException( e, lockOptions );
handlePersistenceException( converted );
return converted;
}
else if ( e instanceof org.hibernate.PessimisticLockException ) {
PersistenceException converted = wrapLockException(e, lockOptions);
PersistenceException converted = wrapLockException( e, lockOptions );
handlePersistenceException( converted );
return converted;
}
@ -1206,17 +1208,17 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
public PersistenceException wrapLockException(HibernateException e, LockOptions lockOptions) {
PersistenceException pe;
if ( e instanceof org.hibernate.OptimisticLockException ) {
org.hibernate.OptimisticLockException ole = (org.hibernate.OptimisticLockException)e;
pe = new OptimisticLockException(ole.getMessage(), ole, ole.getEntity());
org.hibernate.OptimisticLockException ole = ( org.hibernate.OptimisticLockException ) e;
pe = new OptimisticLockException( ole.getMessage(), ole, ole.getEntity() );
}
else if ( e instanceof org.hibernate.PessimisticLockException ) {
org.hibernate.PessimisticLockException ple = (org.hibernate.PessimisticLockException)e;
if (lockOptions !=null && lockOptions.getTimeOut() > -1) {
org.hibernate.PessimisticLockException ple = ( org.hibernate.PessimisticLockException ) e;
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
// assume lock timeout occurred if a timeout or NO WAIT was specified
pe = new LockTimeoutException(ple.getMessage(), ple, ple.getEntity());
pe = new LockTimeoutException( ple.getMessage(), ple, ple.getEntity() );
}
else {
pe = new PessimisticLockException(ple.getMessage(), ple, ple.getEntity());
pe = new PessimisticLockException( ple.getMessage(), ple, ple.getEntity() );
}
}
else {
@ -1224,5 +1226,4 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
}
return pe;
}
}

View File

@ -23,21 +23,19 @@
*/
package org.hibernate.ejb;
import javax.persistence.PersistenceException;
import java.util.List;
import java.util.Map;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.Selection;
import org.hibernate.CacheMode;
import org.hibernate.HibernateException;
import org.hibernate.StaleStateException;
import org.hibernate.LockOptions;
import org.hibernate.StaleStateException;
import org.hibernate.ejb.criteria.ValueHandlerFactory;
import org.hibernate.type.Type;
import java.util.List;
import java.util.Map;
/**
* Additional internal contracts for the Hibernate {@link javax.persistence.EntityManager} implementation.
*
@ -82,6 +80,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
*
* @param e The Hibernate excepton.
* @param lockOptions The lock options in effect at the time of exception (can be null)
*
* @return The JPA-specified exception
*/
public RuntimeException convert(HibernateException e, LockOptions lockOptions);
@ -93,6 +92,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
* Any appropriate/needed calls to {@link #handlePersistenceException} are also made.
*
* @param e The Hibernate excepton.
*
* @return The JPA-specified exception
*/
public RuntimeException convert(HibernateException e);
@ -111,6 +111,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
*
* @param lockModeType is the requested lock type
* @param properties are the lock properties
*
* @return the LockOptions
*/
public LockOptions getLockRequest(LockModeType lockModeType, Map<String, Object> properties);
@ -133,7 +134,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
*
* @return The
*/
public Map<String,Class> getNamedParameterExplicitTypes();
public Map<String, Class> getNamedParameterExplicitTypes();
public ResultMetadataValidator getResultMetadataValidator();
}
@ -146,6 +147,7 @@ public interface HibernateEntityManagerImplementor extends HibernateEntityManage
* @param selection The selection(s)
* @param options The options to use to build the query.
* @param <T> The query type
*
* @return The typed query
*/
public <T> TypedQuery<T> createQuery(String jpaqlString, Class<T> resultClass, Selection selection, Options options);

View File

@ -2,25 +2,25 @@
package org.hibernate.ejb.test.exception;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.cfg.Environment;
import org.hibernate.ejb.test.TestCase;
import org.hibernate.exception.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Emmanuel Bernard
*/
@SuppressWarnings("unchecked")
public class ExceptionTest extends TestCase {
private final Logger log = LoggerFactory.getLogger(ExceptionTest.class);
private final Logger log = LoggerFactory.getLogger( ExceptionTest.class );
public void testOptimisticLockingException() throws Exception {
EntityManager em = getOrCreateEntityManager();
@ -36,10 +36,12 @@ public class ExceptionTest extends TestCase {
Music music2 = em2.find( Music.class, music.getId() );
music2.setName( "HouseMusic" );
em2.getTransaction().commit();
} catch (Exception e){
}
catch ( Exception e ) {
em2.getTransaction().rollback();
throw e;
} finally {
}
finally {
em2.close();
}
@ -48,46 +50,46 @@ public class ExceptionTest extends TestCase {
try {
em.flush();
fail("Should raise an optimistic lock exception");
fail( "Should raise an optimistic lock exception" );
}
catch( OptimisticLockException e) {
catch ( OptimisticLockException e ) {
//success
assertEquals( music, e.getEntity() );
}
catch( Exception e ) {
fail("Should raise an optimistic lock exception");
catch ( Exception e ) {
fail( "Should raise an optimistic lock exception" );
}
finally {
em.getTransaction().rollback();
em.close();
}
}
public void testEntityNotFoundException() throws Exception {
EntityManager em = getOrCreateEntityManager( );
Music music = em.getReference( Music.class, new Integer(-1) );
EntityManager em = getOrCreateEntityManager();
Music music = em.getReference( Music.class, -1 );
try {
music.getName();
fail("Non existent entity should raise an exception when state is accessed");
fail( "Non existent entity should raise an exception when state is accessed" );
}
catch( EntityNotFoundException e ) {
log.debug("success");
catch ( EntityNotFoundException e ) {
log.debug( "success" );
}
finally {
em.close();
}
}
public void testConstraintViolationException() throws Exception {
EntityManager em = getOrCreateEntityManager( );
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Music music = new Music();
music.setName( "Jazz" );
em.persist( music );
Musician lui = new Musician();
lui.setName("Lui Armstrong");
lui.setFavouriteMusic(music);
em.persist(lui);
lui.setName( "Lui Armstrong" );
lui.setFavouriteMusic( music );
em.persist( lui );
em.getTransaction().commit();
try {
em.getTransaction().begin();
@ -96,26 +98,42 @@ public class ExceptionTest extends TestCase {
em.getTransaction().commit();
fail();
}
catch( PersistenceException e ) {
catch ( PersistenceException e ) {
Throwable t = e.getCause();
assertTrue("Should be a constraint violation", t instanceof ConstraintViolationException);
assertTrue( "Should be a constraint violation", t instanceof ConstraintViolationException );
em.getTransaction().rollback();
}
finally {
em.close();
}
}
}
// HHH-4676
public void testInterceptor() throws Exception {
EntityManager em = getOrCreateEntityManager();
em.getTransaction().begin();
Instrument instrument = new Instrument();
instrument.setName( "Guitar" );
try {
em.persist( instrument );
fail( "Commit should have failed." );
}
catch ( RuntimeException e ) {
assertTrue( em.getTransaction().getRollbackOnly() );
}
em.close();
}
@Override
public Map getConfig() {
Map config = super.getConfig();
config.put( Environment.BATCH_VERSIONED_DATA, "false");
config.put( Environment.BATCH_VERSIONED_DATA, "false" );
return config;
}
public Class[] getAnnotatedClasses() {
return new Class[] {
Music.class, Musician.class
Music.class, Musician.class, Instrument.class
};
}
}

View File

@ -0,0 +1,74 @@
// $Id:$
/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.ejb.test.exception;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.PrePersist;
/**
* @author Hardy Ferentschik
*/
@Entity
public class Instrument {
@Id
@GeneratedValue
private int id;
private String name;
private Type type;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
@PrePersist
public void prePersist() {
throw new RuntimeException( "Instrument broken." );
}
public enum Type {
WIND, STRINGS, PERCUSSION
}
}

View File

@ -4,15 +4,15 @@ package org.hibernate.ejb.test.transaction;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
import javax.persistence.TransactionRequiredException;
import javax.persistence.PersistenceException;
import javax.persistence.OptimisticLockException;
import org.hibernate.Session;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.ejb.test.TestCase;
import org.hibernate.stat.Statistics;
import org.hibernate.Session;
/**
* @author Emmanuel Bernard
@ -29,14 +29,14 @@ public class FlushAndTransactionTest extends TestCase {
em.flush();
fail( "flush has to be inside a Tx" );
}
catch (TransactionRequiredException e) {
catch ( TransactionRequiredException e ) {
//success
}
try {
em.lock( book, LockModeType.READ );
fail( "lock has to be inside a Tx" );
}
catch (TransactionRequiredException e) {
catch ( TransactionRequiredException e ) {
//success
}
em.getTransaction().begin();
@ -77,7 +77,7 @@ public class FlushAndTransactionTest extends TestCase {
Book book = new Book();
book.name = "Le petit prince";
EntityManager em = getOrCreateEntityManager();
Statistics stats = ( (HibernateEntityManagerFactory) factory ).getSessionFactory().getStatistics();
Statistics stats = ( ( HibernateEntityManagerFactory ) factory ).getSessionFactory().getStatistics();
stats.clear();
stats.setStatisticsEnabled( true );
@ -120,7 +120,7 @@ public class FlushAndTransactionTest extends TestCase {
Book book = new Book();
book.name = "Le petit prince";
EntityManager em = getOrCreateEntityManager();
Statistics stats = ( (HibernateEntityManagerFactory) factory ).getSessionFactory().getStatistics();
Statistics stats = ( ( HibernateEntityManagerFactory ) factory ).getSessionFactory().getStatistics();
em.getTransaction().begin();
em.persist( book );
@ -164,26 +164,17 @@ public class FlushAndTransactionTest extends TestCase {
em.getTransaction().begin();
Book book = new Book();
book.name = "Java for Dummies";
em.persist( book );
em.close();
book.name = "C# for Dummies";
assertFalse( em.isOpen() );
try {
em.flush();
fail( "direct action on a closed em should fail" );
}
catch (IllegalStateException e) {
catch ( IllegalStateException e ) {
//success
em.getTransaction().rollback();
}
em.getTransaction().commit();
assertFalse( em.isOpen() );
em = getOrCreateEntityManager();
em.getTransaction().begin();
book = em.find( Book.class, book.id );
assertEquals( "C# for Dummies", book.name );
em.remove( book );
em.getTransaction().commit();
em.close();
}
public void testTransactionCommitDoesNotFlush() throws Exception {
@ -196,7 +187,7 @@ public class FlushAndTransactionTest extends TestCase {
em.close();
em = getOrCreateEntityManager();
em.getTransaction().begin();
List result = em.createQuery("select book from Book book where book.name = :title").
List result = em.createQuery( "select book from Book book where book.name = :title" ).
setParameter( "title", book.name ).getResultList();
assertEquals( "EntityManager.commit() should trigger a flush()", 1, result.size() );
em.getTransaction().commit();
@ -213,7 +204,7 @@ public class FlushAndTransactionTest extends TestCase {
em.close();
em = getOrCreateEntityManager();
em.getTransaction().begin();
List result = em.createQuery("select book from Book book where book.name = :title").
List result = em.createQuery( "select book from Book book where book.name = :title" ).
setParameter( "title", book.name ).getResultList();
assertEquals( "EntityManager.commit() should trigger a flush()", 1, result.size() );
assertTrue( em.contains( result.get( 0 ) ) );
@ -232,23 +223,23 @@ public class FlushAndTransactionTest extends TestCase {
em.persist( book );
em.flush();
em.clear();
book.setName( "kitty kid");
book.setName( "kitty kid" );
em.merge( book );
em.flush();
em.clear();
book.setName( "kitty kid2"); //non updated version
book.setName( "kitty kid2" ); //non updated version
em.merge( book );
em.flush();
fail( "optimistic locking exception" );
}
catch (PersistenceException e) {
catch ( PersistenceException e ) {
//success
}
try {
em.getTransaction().commit();
fail( "Commit should be rollbacked" );
}
catch (RollbackException e) {
catch ( RollbackException e ) {
//success
}
finally {
@ -266,18 +257,21 @@ public class FlushAndTransactionTest extends TestCase {
em.persist( book );
em.flush();
em.clear();
book.setName( "kitty kid");
book.setName( "kitty kid" );
em.merge( book );
em.flush();
em.clear();
book.setName( "kitty kid2"); //non updated version
book.setName( "kitty kid2" ); //non updated version
em.unwrap( Session.class ).update( book );
try {
em.getTransaction().commit();
fail( "Commit should be rollbacked" );
}
catch (RollbackException e) {
assertTrue( "During flush a StateStateException is wrapped into a OptimisticLockException", e.getCause() instanceof OptimisticLockException );
catch ( RollbackException e ) {
assertTrue(
"During flush a StateStateException is wrapped into a OptimisticLockException",
e.getCause() instanceof OptimisticLockException
);
}
finally {
em.close();
@ -301,7 +295,7 @@ public class FlushAndTransactionTest extends TestCase {
}
public Class[] getAnnotatedClasses() {
return new Class[]{
return new Class[] {
Book.class
};
}