📄 entitypersister.java
字号:
return update.toStatementString(); } private Update generateUpdate(boolean[] includeProperty) { Update update = new Update() .setTableName( getTableName() ) //.addColumns( getColumnNames() ) .setPrimaryKeyColumnNames( getIdentifierColumnNames() ); for ( int i=0; i<getHydrateSpan(); i++ ) { if ( includeProperty[i] ) update.addColumns( propertyColumnNames[i] ); } if ( optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_VERSION ) { update.setVersionColumnName( getVersionColumnName() ); } return update; } /** * Generate the SQL that pessimistic locks a row by id (and version) */ protected String generateLockString() { SimpleSelect select = new SimpleSelect() .setTableName( getTableName() ) .addColumn( getIdentifierColumnNames()[0] ) .addCondition( getIdentifierColumnNames(), "=?" ); if ( isVersioned() ) { select.addWhereToken("and") .addCondition( getVersionColumnName(), "=?" ); } return select.toStatementString(); } /** * Marshall the fields of a persistent instance to a prepared statement */ protected int dehydrate(Serializable id, Object[] fields, boolean[] includeProperty, PreparedStatement st, SessionImplementor session) throws SQLException, HibernateException { if ( log.isTraceEnabled() ) log.trace( "Dehydrating entity: " + MessageHelper.infoString(this, id) ); int index = 1; for (int j=0; j<getHydrateSpan(); j++) { if ( includeProperty[j] ) { getPropertyTypes()[j].nullSafeSet( st, fields[j], index, session ); index += propertyColumnSpans[j]; } } if ( id!=null ) { getIdentifierType().nullSafeSet( st, id, index, session ); index += getIdentifierColumnNames().length; } return index; } // Execute the SQL: /** * Load an instance using either the <tt>forUpdateLoader</tt> or the outer joining <tt>loader</tt>, * depending upon the value of the <tt>lock</tt> parameter */ public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session) throws HibernateException { if ( log.isTraceEnabled() ) log.trace( "Materializing entity: " + MessageHelper.infoString(this, id) ); try { return ( (UniqueEntityLoader) loaders.get(lockMode) ).load(session, id, optionalObject); } catch (SQLException sqle) { throw new JDBCException("could not load: " + MessageHelper.infoString(this, id), sqle); } } /** * Do a version check */ public void lock(Serializable id, Object version, Object object, LockMode lockMode, SessionImplementor session) throws HibernateException { if ( lockMode!=LockMode.NONE ) { if ( log.isTraceEnabled() ) { log.trace( "Locking entity: " + MessageHelper.infoString(this, id) ); if ( isVersioned() ) log.trace("Version: " + version); } try { PreparedStatement st = session.getBatcher().prepareStatement( (String) lockers.get(lockMode) ); try { getIdentifierType().nullSafeSet(st, id, 1, session); if ( isVersioned() ) { getVersionType().nullSafeSet(st, version, getIdentifierColumnNames().length+1, session); } ResultSet rs = st.executeQuery(); try { if ( !rs.next() ) throw new StaleObjectStateException( getMappedClass(), id ); } finally { rs.close(); } } catch(SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); throw sqle; } finally { session.getBatcher().closeStatement(st); } } catch (SQLException sqle) { throw new JDBCException("could not lock: " + MessageHelper.infoString(this, id), sqle ); } } } public Serializable insert(Object[] fields, Object object, SessionImplementor session) throws HibernateException { if ( useDynamicInsert() ) { boolean[] notNull = getNotNullInsertableColumns(fields); return insert(fields, notNull, generateInsertString(true, notNull), object, session); } else { return insert(fields, getPropertyInsertability(), getSQLIdentityInsertString(), object, session); } } public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session) throws HibernateException { if ( useDynamicInsert() ) { boolean[] notNull = getNotNullInsertableColumns(fields); insert(id, fields, notNull, generateInsertString(false, notNull), object, session); } else { insert(id, fields, getPropertyInsertability(), getSQLInsertString(), object, session); } } /** * Persist an object */ public void insert(Serializable id, Object[] fields, boolean[] notNull, String sql, Object object, SessionImplementor session) throws HibernateException { if ( log.isTraceEnabled() ) { log.trace( "Inserting entity: " + MessageHelper.infoString(this, id) ); if ( isVersioned() ) log.trace( "Version: " + Versioning.getVersion(fields, this) ); } try { // Render the SQL query PreparedStatement statement = session.getBatcher().prepareBatchStatement(sql); try { // Write the values of fields onto the prepared statement - we MUST use the state at the time the // insert was issued (cos of foreign key constraints). Not necessarily the object's current state dehydrate(id, fields, notNull, statement, session); session.getBatcher().addToBatch(1); //statement.executeUpdate(); } catch (SQLException sqle) { session.getBatcher().abortBatch(sqle); throw sqle; } } catch (SQLException sqle) { throw new JDBCException( "could not insert: " + MessageHelper.infoString(this, id), sqle ); } } /** * Persist an object, using a natively generated identifier */ public Serializable insert(Object[] fields, boolean[] notNull, String sql, Object object, SessionImplementor session) throws HibernateException { if ( log.isTraceEnabled() ) { log.trace("Inserting entity: " + getClassName() + " (native id)"); if ( isVersioned() ) log.trace( "Version: " + Versioning.getVersion(fields, this) ); } try { // Render the SQL query PreparedStatement statement = session.getBatcher().prepareStatement(sql); try { dehydrate(null, fields, notNull, statement, session); statement.executeUpdate(); } catch (SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); throw sqle; } finally { session.getBatcher().closeStatement(statement); } // fetch the generated id: PreparedStatement idselect = session.getBatcher().prepareStatement( sqlIdentitySelect() ); try { ResultSet rs = idselect.executeQuery(); final Serializable id; try { if ( !rs.next() ) throw new HibernateException("The database returned no natively generated identity value"); id = IdentifierGeneratorFactory.get( rs, getIdentifierType(), session, object ); } finally { rs.close(); } log.debug("Natively generated identity: " + id); return id; } catch(SQLException sqle) { JDBCExceptionReporter.logExceptions(sqle); throw sqle; } finally { session.getBatcher().closeStatement(idselect); } } catch (SQLException sqle) { throw new JDBCException( "could not insert: " + MessageHelper.infoString(this), sqle ); } } /** * Delete an object */ public void delete(Serializable id, Object version, Object object, SessionImplementor session) throws HibernateException { if ( log.isTraceEnabled() ) { log.trace( "Deleting entity: " + MessageHelper.infoString(this, id) ); if ( isVersioned() ) log.trace( "Version: " + version ); } try { //Render the SQL query final PreparedStatement statement;// = session.getPreparedStatement( sqlDelete() ); if ( isVersioned() ) { statement = session.getBatcher().prepareStatement( getSQLDeleteString() ); } else { statement = session.getBatcher().prepareBatchStatement( getSQLDeleteString() ); } try { // Do the key. The key is immutable so we can use the _current_ object state - not necessarily // the state at the time the delete was issued getIdentifierType().nullSafeSet( statement, id, 1, session ); // We should use the _current_ object state (ie. after any updates that occurred during flush) if ( isVersioned() ) { getVersionType().nullSafeSet( statement, version, getIdentifierColumnNames().length + 1, session ); check( statement.executeUpdate(), id ); } else { session.getBatcher().addToBatch(1); } //check( statement.executeUpdate(), id ); } catch (SQLException sqle) { if ( !isVersioned() ) { session.getBatcher().abortBatch(sqle); } else { JDBCExceptionReporter.logExceptions(sqle); } throw sqle; } finally { if ( isVersioned() ) session.getBatcher().closeStatement(statement); } } catch (SQLException sqle) { throw new JDBCException( "could not delete: " + MessageHelper.infoString(this, id), sqle ); } } /** * Update an object */ public void update(Serializable id, Object[] fields, int[] dirtyFields, Object[] oldFields, Object oldVersion, Object object, SessionImplementor session) throws HibernateException { //note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-before-update // oldFields==null just means we had no snapshot to begin with (we might have used select-before-update to get the dirtyFields) final boolean[] propsToUpdate; final String updateString; if ( useDynamicUpdate() && dirtyFields!=null ) { propsToUpdate = getPropertiesToUpdate(dirtyFields); updateString = generateUpdateString(propsToUpdate, oldFields); //don't need to check property updatability (dirty checking algorithm handles that) } else { propsToUpdate = getPropertyUpdateability(); updateString = getSQLUpdateString(); } update(id, fields, oldFields, propsToUpdate, oldVersion, object, updateString, session); } protected void update(Serializable id, Object[] fields, Object[] oldFields, boolean[] includeProperty, Object oldVersion, Object object, String sql, SessionImplementor session) throws HibernateException { if ( log.isTraceEnabled() ) { log.trace( "Updating entity: " + MessageHelper.infoString(this, id) ); if ( isVersioned() ) log.trace( "Existing version: " + oldVersion + " -> New version: " + fields[ getVersionProperty() ] ); } if (!hasUpdateableColumns) return; try { final PreparedStatement statement; if ( isVersioned() ) { statement = session.getBatcher().prepareStatement(sql); } else { statement = session.getBatcher().prepareBatchStatement(sql); } try { //Now write the values of fields onto the prepared statement int index = dehydrate(id, fields, includeProperty, statement, session); if ( isVersioned() && optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_VERSION ) { getVersionType().nullSafeSet( statement, oldVersion, index, session ); check( statement.executeUpdate(), id ); } else if ( optimisticLockMode()>Versioning.OPTIMISTIC_LOCK_VERSION && oldFields!=null ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -