@Override public Serializable insert(String entityName, Object entity) { errorIfClosed(); EntityPersister persister = getEntityPersister( entityName, entity ); Serializable id = persister.getIdentifierGenerator().generate( this, entity ); Object[] state = persister.getPropertyValues( entity ); if ( persister.isVersioned() ) { boolean substitute = Versioning.seedVersion( state, persister.getVersionProperty(), persister.getVersionType(), this ); if ( substitute ) { persister.setPropertyValues( entity, state ); } } if ( id == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) { id = persister.insert(state, entity, this); } else { persister.insert(id, state, entity, this); } persister.setIdentifier( entity, id, this ); return id; }
/** * Override in order to unquote the primary key column name, else it breaks (at least on Postgres) */ @Override public Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException { session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().executeUpdate(insert); ResultSet rs = null; try { rs = insert.getGeneratedKeys(); return IdentifierGeneratorHelper.getGeneratedIdentity( rs, unquotedIdentifier(persister.getRootTableKeyColumnNames()[0]), persister.getIdentifierType() ); } finally { if (rs != null) { session.getTransactionCoordinator().getJdbcCoordinator().release(rs, insert); } } }
@Override public IntegralDataTypeHolder execute(Connection connection) throws SQLException { IntegralDataTypeHolder value = IdentifierGeneratorHelper .getIntegralDataTypeHolder(identifierType .getReturnedClass()); int rows; do { statementLogger.logStatement(selectQuery, FormatStyle.BASIC.getFormatter()); onSelect(connection, value); statementLogger.logStatement(updateQuery, FormatStyle.BASIC.getFormatter()); rows = onUpdate(connection, value); } while (rows == ZERO_ROWS); return value; }
/** * Prepares the save call using a newly generated id. * * @param entity The entity to be saved * @param entityName The entity-name for the entity to be saved * @param anything Generally cascade-specific information. * @param source The session which is the source of this save event. * @param requiresImmediateIdAccess does the event context require * access to the identifier immediately after execution of this method (if * not, post-insert style id generators may be postponed if we are outside * a transaction). * * @return The id used to save the entity; may be null depending on the * type of id generator used and the requiresImmediateIdAccess value */ protected Serializable saveWithGeneratedId( Object entity, String entityName, Object anything, EventSource source, boolean requiresImmediateIdAccess) { EntityPersister persister = source.getEntityPersister( entityName, entity ); Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity ); if ( generatedId == null ) { throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() ); } else if ( generatedId == IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR ) { return source.getIdentifier( entity ); } else if ( generatedId == IdentifierGeneratorHelper.POST_INSERT_INDICATOR ) { return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess ); } else { // TODO: define toString()s for generators if ( LOG.isDebugEnabled() ) { LOG.debugf( "Generated identifier: %s, using strategy: %s", persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ), persister.getIdentifierGenerator().getClass().getName() ); } return performSave( entity, generatedId, persister, false, anything, source, true ); } }
@Override public Object getDefaultValue(Object currentValue) { return IdentifierGeneratorHelper.getIntegralDataTypeHolder( currentValue.getClass() ) .initialize( -1L ) .makeValue(); }
private IntegralDataTypeHolder makeValue() { return IdentifierGeneratorHelper.getIntegralDataTypeHolder( identifierType.getReturnedClass() ); }
private IntegralDataTypeHolder makeValue() { return IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType ); }
@Override public AccessCallback buildCallback(final SessionImplementor session) { return new AccessCallback() { @Override public IntegralDataTypeHolder getNextValue() { accessCounter++; try { final PreparedStatement st = session.getTransactionCoordinator().getJdbcCoordinator().getStatementPreparer().prepareStatement( sql ); try { final ResultSet rs = session.getTransactionCoordinator().getJdbcCoordinator().getResultSetReturn().extract( st ); try { rs.next(); final IntegralDataTypeHolder value = IdentifierGeneratorHelper.getIntegralDataTypeHolder( numberType ); value.initialize( rs, 1 ); if ( LOG.isDebugEnabled() ) { LOG.debugf( "Sequence value obtained: %s", value.makeValue() ); } return value; } finally { try { session.getTransactionCoordinator().getJdbcCoordinator().release( rs, st ); } catch( Throwable ignore ) { // intentionally empty } } } finally { session.getTransactionCoordinator().getJdbcCoordinator().release( st ); } } catch ( SQLException sqle) { throw session.getFactory().getSQLExceptionHelper().convert( sqle, "could not get next sequence value", sql ); } } @Override public String getTenantIdentifier() { return session.getTenantIdentifier(); } }; }