/** * Return the identifier of the persistent or transient object, or throw * an exception if the instance is "unsaved" * <p/> * Used by OneToOneType and ManyToOneType to determine what id value should * be used for an object that may or may not be associated with the session. * This does a "best guess" using any/all info available to use (not just the * EntityEntry). * * @param entityName The name of the entity * @param object The entity instance * @param session The session * * @return The identifier * * @throws TransientObjectException if the entity is transient (does not yet have an identifier) */ public static Serializable getEntityIdentifierIfNotUnsaved( final String entityName, final Object object, final SessionImplementor session) throws TransientObjectException { if ( object == null ) { return null; } else { Serializable id = session.getContextEntityIdentifier( object ); if ( id == null ) { // context-entity-identifier returns null explicitly if the entity // is not associated with the persistence context; so make some // deeper checks... if ( isTransient( entityName, object, Boolean.FALSE, session ) ) { throw new TransientObjectException( "object references an unsaved transient instance - save the transient instance before flushing: " + (entityName == null ? session.guessEntityName( object ) : entityName) ); } id = session.getEntityPersister( entityName, object ).getIdentifier( object, session ); } return id; } }
@Override public LockMode getCurrentLockMode(Object object) throws HibernateException { errorIfClosed(); checkTransactionSynchStatus(); if ( object == null ) { throw new NullPointerException( "null object passed to getCurrentLockMode()" ); } if ( object instanceof HibernateProxy ) { object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this); if ( object == null ) { return LockMode.NONE; } } EntityEntry e = persistenceContext.getEntry(object); if ( e == null ) { throw new TransientObjectException( "Given object not associated with the session" ); } if ( e.getStatus() != Status.MANAGED ) { throw new ObjectDeletedException( "The given object was deleted", e.getId(), e.getPersister().getEntityName() ); } return e.getLockMode(); }
@Override public Serializable getIdentifier(Object object) throws HibernateException { errorIfClosed(); checkTransactionSynchStatus(); if ( object instanceof HibernateProxy ) { LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer(); if ( li.getSession() != this ) { throw new TransientObjectException( "The proxy was not associated with this session" ); } return li.getIdentifier(); } else { EntityEntry entry = persistenceContext.getEntry(object); if ( entry == null ) { throw new TransientObjectException( "The instance was not associated with this session" ); } return entry.getId(); } }
@Override public String getEntityName(Object object) { errorIfClosed(); checkTransactionSynchStatus(); if (object instanceof HibernateProxy) { if ( !persistenceContext.containsProxy( object ) ) { throw new TransientObjectException("proxy was not associated with the session"); } object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(); } EntityEntry entry = persistenceContext.getEntry(object); if ( entry == null ) { throwTransientObjectException( object ); } return entry.getPersister().getEntityName(); }
/** * Determine the id to use for updating. * * @param entity The entity. * @param persister The entity persister * @param requestedId The requested identifier * @param session The session * * @return The id. * * @throws TransientObjectException If the entity is considered transient. */ protected Serializable getUpdateId( Object entity, EntityPersister persister, Serializable requestedId, SessionImplementor session) { // use the id assigned to the instance Serializable id = persister.getIdentifier( entity, session ); if ( id == null ) { // assume this is a newly instantiated transient object // which should be saved rather than updated throw new TransientObjectException( "The given object has a null identifier: " + persister.getEntityName() ); } else { return id; } }
/** * Return the identifier of the persistent or transient object, or throw * an exception if the instance is "unsaved" * * Used by OneToOneType and ManyToOneType to determine what id value should * be used for an object that may or may not be associated with the session. * This does a "best guess" using any/all info available to use (not just the * EntityEntry). */ public static Serializable getEntityIdentifierIfNotUnsaved( final String entityName, final Object object, final SessionImplementor session) throws HibernateException { if ( object == null ) { return null; } else { Serializable id = session.getContextEntityIdentifier( object ); if ( id == null ) { // context-entity-identifier returns null explicitly if the entity // is not associated with the persistence context; so make some // deeper checks... if ( isTransient(entityName, object, Boolean.FALSE, session) ) { throw new TransientObjectException( "object references an unsaved transient instance - save the transient instance before flushing: " + (entityName == null ? session.guessEntityName( object ) : entityName) ); } id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() ); } return id; } }
/** * Determine the id to use for updating. * * @param entity The entity. * @param persister The entity persister * @param requestedId The requested identifier * @param entityMode The entity mode. * * @return The id. * * @throws TransientObjectException If the entity is considered transient. */ protected Serializable getUpdateId( Object entity, EntityPersister persister, Serializable requestedId, EntityMode entityMode) { // use the id assigned to the instance Serializable id = persister.getIdentifier( entity, entityMode ); if ( id == null ) { // assume this is a newly instantiated transient object // which should be saved rather than updated throw new TransientObjectException( "The given object has a null identifier: " + persister.getEntityName() ); } else { return id; } }
public LockMode getCurrentLockMode(Object object) throws HibernateException { errorIfClosed(); checkTransactionSynchStatus(); if ( object == null ) { throw new NullPointerException( "null object passed to getCurrentLockMode()" ); } if ( object instanceof HibernateProxy ) { object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this); if ( object == null ) { return LockMode.NONE; } } EntityEntry e = persistenceContext.getEntry(object); if ( e == null ) { throw new TransientObjectException( "Given object not associated with the session" ); } if ( e.getStatus() != Status.MANAGED ) { throw new ObjectDeletedException( "The given object was deleted", e.getId(), e.getPersister().getEntityName() ); } return e.getLockMode(); }
public Serializable getIdentifier(Object object) throws HibernateException { errorIfClosed(); checkTransactionSynchStatus(); if ( object instanceof HibernateProxy ) { LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer(); if ( li.getSession() != this ) { throw new TransientObjectException( "The proxy was not associated with this session" ); } return li.getIdentifier(); } else { EntityEntry entry = persistenceContext.getEntry(object); if ( entry == null ) { throw new TransientObjectException( "The instance was not associated with this session" ); } return entry.getId(); } }
public String getEntityName(Object object) { errorIfClosed(); checkTransactionSynchStatus(); if (object instanceof HibernateProxy) { if ( !persistenceContext.containsProxy( object ) ) { throw new TransientObjectException("proxy was not associated with the session"); } object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(); } EntityEntry entry = persistenceContext.getEntry(object); if ( entry == null ) { throwTransientObjectException( object ); } return entry.getPersister().getEntityName(); }
public void testOneToOneGeneratedIds() { try { Session s = openSession(); s.beginTransaction(); Parent p = new Parent( "parent" ); ParentInfo info = new ParentInfo( "xyz" ); p.setInfo( info ); info.setOwner( p ); s.persist( p ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testOneToOneAssignedIds() { try { Session s = openSession(); s.beginTransaction(); ParentAssigned p = new ParentAssigned( new Long( 1 ), "parent" ); ParentInfoAssigned info = new ParentInfoAssigned( "something secret" ); p.setInfo( info ); info.setOwner( p ); s.persist( p ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testManyToOnePropertyRefGeneratedIds() { try { Session s = openSession(); s.beginTransaction(); Parent p = new Parent( "parent" ); Other other = new Other(); other.setOwner( p ); s.persist( other ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testManyToOnePropertyRefAssignedIds() { try { Session s = openSession(); s.beginTransaction(); ParentAssigned p = new ParentAssigned( new Long( 1 ), "parent" ); OtherAssigned other = new OtherAssigned( new Long( 2 ) ); other.setOwner( p ); s.persist( other ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testOneToOnePropertyRefGeneratedIds() { try { Session s = openSession(); s.beginTransaction(); Child c2 = new Child( "c2" ); ChildInfo info = new ChildInfo( "blah blah blah" ); c2.setInfo( info ); info.setOwner( c2 ); s.persist( c2 ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception : " + e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testOneToOnePropertyRefAssignedIds() { try { Session s = openSession(); s.beginTransaction(); ChildAssigned c2 = new ChildAssigned( new Long( 3 ), "c3" ); ChildInfoAssigned info = new ChildInfoAssigned( new Long( 4 ), "blah blah blah" ); c2.setInfo( info ); info.setOwner( c2 ); s.persist( c2 ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception : " + e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) { try { PreparedStatement st = session.getTransactionCoordinator() .getJdbcCoordinator() .getStatementPreparer() .prepareStatement( sql ); try { getKeyType().nullSafeSet( st, key, 1, session ); indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session ); ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { return rs.next(); } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } } catch ( TransientObjectException e ) { return false; } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle ) { throw getSQLExceptionHelper().convert( sqle, "could not check row existence: " + MessageHelper.collectionInfoString( this, key, getFactory() ), sqlSelectSizeString ); } }
private void setEntityReadOnly(Object entity, boolean readOnly) { final EntityEntry entry = getEntry( entity ); if ( entry == null ) { throw new TransientObjectException( "Instance was not associated with this persistence context" ); } entry.setReadOnly( readOnly, entity ); hasNonReadOnlyEntities = hasNonReadOnlyEntities || ! readOnly; }
private void errorIfReadOnlySettingNotAvailable() { if ( session == null ) { throw new TransientObjectException( "Proxy is detached (i.e, session is null). The read-only/modifiable setting is only accessible when the proxy is associated with an open session." ); } if ( session.isClosed() ) { throw new SessionException( "Session is closed. The read-only/modifiable setting is only accessible when the proxy is associated with an open session." ); } }
/** * Handle the given lock event. * * @param event The lock event to be handled. * @throws HibernateException */ public void onLock(LockEvent event) throws HibernateException { if ( event.getObject() == null ) { throw new NullPointerException( "attempted to lock null" ); } if ( event.getLockMode() == LockMode.WRITE ) { throw new HibernateException( "Invalid lock mode for lock()" ); } if ( event.getLockMode() == LockMode.UPGRADE_SKIPLOCKED ) { LOG.explicitSkipLockedLockCombo(); } SessionImplementor source = event.getSession(); Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() ); //TODO: if object was an uninitialized proxy, this is inefficient, // resulting in two SQL selects EntityEntry entry = source.getPersistenceContext().getEntry(entity); if (entry==null) { final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); final Serializable id = persister.getIdentifier( entity, source ); if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) { throw new TransientObjectException( "cannot lock an unsaved transient instance: " + persister.getEntityName() ); } entry = reassociate(event, entity, id, persister); cascadeOnLock(event, persister, entity); } upgradeLock( entity, entry, event.getLockOptions(), event.getSession() ); }
private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException { try { return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName( value ), value, session ); } catch (TransientObjectException toe) { return null; } }
@Test public void testMergeTransactionDoesNotCascadePayee() throws Exception { Transaction transaction = createTransaction(); transaction.setPayee(new Payee("unsaved payee")); try { transactionDao.merge(transaction); } catch (UndeclaredThrowableException ex) { assertThat(ex.getCause().getCause()).isInstanceOf(TransientObjectException.class); assertThat(ex.getCause().getCause().getMessage()).endsWith(Payee.class.getName()); } }
private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) { try { PreparedStatement st = session.getBatcher().prepareSelectStatement(sql); try { getKeyType().nullSafeSet(st, key, 1, session); indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session ); ResultSet rs = st.executeQuery(); try { return rs.next(); } finally { rs.close(); } } catch( TransientObjectException e ) { return false; } finally { session.getBatcher().closeStatement( st ); } } catch (SQLException sqle) { throw JDBCExceptionHelper.convert( getFactory().getSQLExceptionConverter(), sqle, "could not check row existence: " + MessageHelper.collectionInfoString( this, key, getFactory() ), sqlSelectSizeString ); } }
public void setReadOnly(Object entity, boolean readOnly) { EntityEntry entry = getEntry(entity); if (entry==null) { throw new TransientObjectException("Instance was not associated with the session"); } entry.setReadOnly(readOnly, entity); hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly; }
public void noCascade( EventSource session, Object child, Object parent, EntityPersister persister, int propertyIndex) { if ( child == null ) { return; } Type type = persister.getPropertyTypes()[propertyIndex]; if ( type.isEntityType() ) { String childEntityName = ( ( EntityType ) type ).getAssociatedEntityName( session.getFactory() ); if ( ! isInManagedState( child, session ) && ! ( child instanceof HibernateProxy ) //a proxy cannot be transient and it breaks ForeignKeys.isTransient && ForeignKeys.isTransient( childEntityName, child, null, session ) ) { String parentEntiytName = persister.getEntityName(); String propertyName = persister.getPropertyNames()[propertyIndex]; throw new TransientObjectException( "object references an unsaved transient instance - " + "save the transient instance before flushing: " + parentEntiytName + "." + propertyName + " -> " + childEntityName ); } } }
/** * @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object) */ public Serializable generate(SessionImplementor sessionImplementor, Object object) throws HibernateException { Session session = (Session) sessionImplementor; Object associatedObject = sessionImplementor.getFactory() .getClassMetadata( entityName ) .getPropertyValue( object, propertyName, session.getEntityMode() ); if ( associatedObject == null ) { throw new IdentifierGenerationException( "attempted to assign id from null one-to-one property: " + propertyName ); } EntityType type = (EntityType) sessionImplementor.getFactory() .getClassMetadata( entityName ) .getPropertyType( propertyName ); Serializable id; try { id = ForeignKeys.getEntityIdentifierIfNotUnsaved( type.getAssociatedEntityName(), associatedObject, sessionImplementor ); } catch (TransientObjectException toe) { id = session.save( type.getAssociatedEntityName(), associatedObject ); } if ( session.contains(object) ) { //abort the save (the object is already saved by a circular cascade) return IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR; //throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association"); } return id; }
/** Handle the given lock event. * * @param event The lock event to be handled. * @throws HibernateException */ public void onLock(LockEvent event) throws HibernateException { if ( event.getObject() == null ) { throw new NullPointerException( "attempted to lock null" ); } if ( event.getLockMode() == LockMode.WRITE ) { throw new HibernateException( "Invalid lock mode for lock()" ); } SessionImplementor source = event.getSession(); Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() ); //TODO: if object was an uninitialized proxy, this is inefficient, // resulting in two SQL selects EntityEntry entry = source.getPersistenceContext().getEntry(entity); if (entry==null) { final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity ); final Serializable id = persister.getIdentifier( entity, source.getEntityMode() ); if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) { throw new TransientObjectException( "cannot lock an unsaved transient instance: " + persister.getEntityName() ); } entry = reassociate(event, entity, id, persister); cascadeOnLock(event, persister, entity); } upgradeLock( entity, entry, event.getLockMode(), source ); }
private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException { try { return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName(value), value, session ); } catch (TransientObjectException toe) { return null; } }
public void testManyToOneGeneratedIdsOnSave() { // NOTES: Child defines a many-to-one back to its Parent. This // association does not define persist cascading (which is natural; // a child should not be able to create its parent). try { Session s = openSession(); s.beginTransaction(); Parent p = new Parent( "parent" ); Child c = new Child( "child" ); c.setParent( p ); s.save( c ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testManyToOneGeneratedIds() { // NOTES: Child defines a many-to-one back to its Parent. This // association does not define persist cascading (which is natural; // a child should not be able to create its parent). try { Session s = openSession(); s.beginTransaction(); Parent p = new Parent( "parent" ); Child c = new Child( "child" ); c.setParent( p ); s.persist( c ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
public void testManyToOneAssignedIds() { // NOTES: Child defines a many-to-one back to its Parent. This // association does not define persist cascading (which is natural; // a child should not be able to create its parent). try { Session s = openSession(); s.beginTransaction(); ParentAssigned p = new ParentAssigned( new Long( 1 ), "parent" ); ChildAssigned c = new ChildAssigned( new Long( 2 ), "child" ); c.setParent( p ); s.persist( c ); try { s.getTransaction().commit(); fail( "expecting TransientObjectException on flush" ); } catch( TransientObjectException e ) { // expected result log.trace( "handled expected exception", e ); s.getTransaction().rollback(); } finally { s.close(); } } finally { cleanupData(); } }
private void throwTransientObjectException(Object object) throws HibernateException { throw new TransientObjectException( "object references an unsaved transient instance - save the transient instance before flushing: " + guessEntityName(object) ); }
/** * Return the identifier value of the given entity as associated with this session. An * exception is thrown if the given entity instance is transient or detached in * relation to this session. * * @param domainObject * a persistent instance * @return the identifier; if the instance is transient or associated with a different * session <code>HibernateException</code>, returns * <code>INVALID_VALUE_LONG_BOXED</code> * @see edu.utah.further.core.api.data.DataService#getIdentifier(edu.utah.further.core.api.data.PersistentEntity, * java.io.Serializable) */ @Override public Serializable getIdentifier(final PersistentEntity<?> domainObject) { try { return getCurrentSession().getIdentifier(domainObject); } catch (final TransientObjectException e) { return INVALID_VALUE_BOXED_LONG; } }