📄 abstractentitypersister.java
字号:
.append( getVersionColumnName() )
.append("=?");
}*/
return select.setSelectClause( selectClause )
.setFromClause( fromClause )
.setOuterJoins( "", "" )
.setWhereClause( whereClause )
.toStatementString();
}
/**
* 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, getFactory() ) );
if ( isVersioned() ) log.trace( "Version: " + version );
}
final String sql = getLockString( lockMode );
try {
PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
try {
getIdentifierType().nullSafeSet( st, id, 1, session );
if ( isVersioned() ) {
getVersionType().nullSafeSet( st, version, getIdentifierColumnSpan() + 1, session );
}
ResultSet rs = st.executeQuery();
try {
if ( !rs.next() ) {
if ( getFactory().getStatistics().isStatisticsEnabled() ) {
getFactory().getStatisticsImplementor()
.optimisticFailure( getEntityName() );
}
throw new StaleObjectStateException( getEntityName(), id );
}
}
finally {
rs.close();
}
}
finally {
session.getBatcher().closeStatement( st );
}
}
catch ( SQLException sqle ) {
throw JDBCExceptionHelper.convert(
getFactory().getSQLExceptionConverter(),
sqle,
"could not lock: " +
MessageHelper.infoString( this, id, getFactory() ),
sql
);
}
}
}
/**
* Retrieve the version number
*/
public Object getCurrentVersion(Serializable id, SessionImplementor session) throws HibernateException {
if ( log.isTraceEnabled() ) {
log.trace( "Getting version: " + MessageHelper.infoString( this, id, getFactory() ) );
}
try {
PreparedStatement st = session.getBatcher().prepareSelectStatement( getVersionSelectString() );
try {
getIdentifierType().nullSafeSet( st, id, 1, session );
ResultSet rs = st.executeQuery();
try {
if ( !rs.next() ) return null;
if ( !isVersioned() ) return this;
return getVersionType().nullSafeGet( rs, getVersionColumnName(), session, null );
}
finally {
rs.close();
}
}
finally {
session.getBatcher().closeStatement( st );
}
}
catch ( SQLException sqle ) {
throw JDBCExceptionHelper.convert(
getFactory().getSQLExceptionConverter(),
sqle,
"could not retrieve version: " +
MessageHelper.infoString( this, id, getFactory() ),
getVersionSelectString()
);
}
}
/**
* Generate the SQL that pessimistic locks a row by id (and version)
*/
protected String generateLockString(LockMode lockMode) {
SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
.setLockMode( lockMode )
.setTableName( getVersionedTableName() )
.addColumn( rootTableKeyColumnNames[0] )
.addCondition( rootTableKeyColumnNames, "=?" );
if ( isVersioned() ) {
select.addCondition( getVersionColumnName(), "=?" );
}
if ( getFactory().getSettings().isCommentsEnabled() ) {
select.setComment( "lock " + getEntityName() );
}
return select.toStatementString();
}
protected void initLockers() {
lockers.put( LockMode.READ, generateLockString( LockMode.READ ) );
lockers.put( LockMode.UPGRADE, generateLockString( LockMode.UPGRADE ) );
lockers.put( LockMode.UPGRADE_NOWAIT, generateLockString( LockMode.UPGRADE_NOWAIT ) );
}
public String[] toColumns(String alias, String propertyName) throws QueryException {
return propertyMapping.toColumns( alias, propertyName );
}
public String[] toColumns(String propertyName) throws QueryException {
return propertyMapping.getColumnNames( propertyName );
}
public Type toType(String propertyName) throws QueryException {
return propertyMapping.toType( propertyName );
}
public String[] getPropertyColumnNames(String propertyName) {
return propertyMapping.getColumnNames( propertyName );
}
/**
* Warning:
* When there are duplicated property names in the subclasses
* of the class, this method may return the wrong table
* number for the duplicated subclass property (note that
* SingleTableEntityPersister defines an overloaded form
* which takes the entity name.
*/
public int getSubclassPropertyTableNumber(String propertyPath) {
final String rootPropertyName = StringHelper.root(propertyPath);
Type type = propertyMapping.toType(rootPropertyName);
if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) {
return 0;
}
//Enable for HHH-440, which we don't like:
/*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
String unrooted = StringHelper.unroot(propertyName);
int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
if ( idx != -1 ) {
return getSubclassColumnTableNumberClosure()[idx];
}
}*/
int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), rootPropertyName); //TODO: optimize this better!
return index==-1 ? 0 : getSubclassPropertyTableNumber(index);
}
protected String generateTableAlias(String rootAlias, int tableNumber) {
if ( tableNumber == 0 ) return rootAlias;
StringBuffer buf = new StringBuffer().append( rootAlias );
if ( !rootAlias.endsWith( "_" ) ) buf.append( '_' );
return buf.append( tableNumber ).append( '_' ).toString();
}
public String[] toColumns(String name, final int i) {
final String alias = generateTableAlias( name, getSubclassPropertyTableNumber( i ) );
String[] cols = getSubclassPropertyColumnNames( i );
String[] templates = getSubclassPropertyFormulaTemplateClosure()[i];
String[] result = new String[cols.length];
for ( int j = 0; j < cols.length; j++ ) {
if ( cols[j] == null ) {
result[j] = StringHelper.replace( templates[j], Template.TEMPLATE, alias );
}
else {
result[j] = StringHelper.qualify( alias, cols[j] );
}
}
return result;
}
private int getSubclassPropertyIndex(String propertyName) {
return ArrayHelper.indexOf(subclassPropertyNameClosure, propertyName);
}
protected String[] getPropertySubclassNames() {
return propertySubclassNames;
}
public String[] getPropertyColumnNames(int i) {
return propertyColumnNames[i];
}
protected int getPropertyColumnSpan(int i) {
return propertyColumnSpans[i];
}
protected boolean hasFormulaProperties() {
return hasFormulaProperties;
}
public FetchMode getFetchMode(int i) {
return subclassPropertyFetchModeClosure[i];
}
public CascadeStyle getCascadeStyle(int i) {
return subclassPropertyCascadeStyleClosure[i];
}
public Type getSubclassPropertyType(int i) {
return subclassPropertyTypeClosure[i];
}
public String getSubclassPropertyName(int i) {
return subclassPropertyNameClosure[i];
}
public int countSubclassProperties() {
return subclassPropertyTypeClosure.length;
}
public String[] getSubclassPropertyColumnNames(int i) {
return subclassPropertyColumnNameClosure[i];
}
public boolean isDefinedOnSubclass(int i) {
return propertyDefinedOnSubclass[i];
}
protected String[][] getSubclassPropertyFormulaTemplateClosure() {
return subclassPropertyFormulaTemplateClosure;
}
protected Type[] getSubclassPropertyTypeClosure() {
return subclassPropertyTypeClosure;
}
protected String[][] getSubclassPropertyColumnNameClosure() {
return subclassPropertyColumnNameClosure;
}
protected String[] getSubclassPropertyNameClosure() {
return subclassPropertyNameClosure;
}
protected String[] getSubclassPropertySubclassNameClosure() {
return subclassPropertySubclassNameClosure;
}
protected String[] getSubclassColumnClosure() {
return subclassColumnClosure;
}
protected String[] getSubclassColumnAliasClosure() {
return subclassColumnAliasClosure;
}
protected String[] getSubclassFormulaClosure() {
return subclassFormulaClosure;
}
protected String[] getSubclassFormulaTemplateClosure() {
return subclassFormulaTemplateClosure;
}
protected String[] getSubclassFormulaAliasClosure() {
return subclassFormulaAliasClosure;
}
public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix) {
String rawAliases[] = ( String[] ) subclassPropertyAliases.get( propertyName );
if ( rawAliases == null ) return null;
String result[] = new String[rawAliases.length];
for ( int i = 0; i < rawAliases.length; i++ ) {
result[i] = new Alias( suffix ).toUnquotedAliasString( rawAliases[i] );
}
return result;
}
public String[] getSubclassPropertyColumnNames(String propertyName) {
//TODO: should we allow suffixes on these ?
return ( String[] ) subclassPropertyColumnNames.get( propertyName );
}
//This is really ugly, but necessary:
/**
* Must be called by subclasses, at the end of their constructors
*/
protected void initSubclassPropertyAliasesMap(PersistentClass model) throws MappingException {
// ALIASES
internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosureIterator() );
// aliases for identifier ( alias.id )
subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() );
subclassPropertyColumnNames.put( ENTITY_ID, getIdentifierColumnNames() );
// aliases named identifier ( alias.idname )
if ( hasIdentifierProperty() ) {
subclassPropertyAliases.put( getIdentifierPropertyName(), getIdentifierAliases() );
subclassPropertyColumnNames.put( getIdentifierPropertyName(), getIdentifierColumnNames() );
}
// aliases for composite-id's
if ( getIdentifierType().isComponentType() ) {
// Fetch embedded identifiers propertynames from the "virtual" identifier component
AbstractComponentType componentId = ( AbstractComponentType ) getIdentifierType();
String[] idPropertyNames = componentId.getPropertyNames();
String[] idAliases = getIdentifierAliases();
String[] idColumnNames = getIdentifierColumnNames();
for ( int i = 0; i < idPropertyNames.length; i++ ) {
subclassPropertyAliases.put(
ENTITY_ID + "." + idPropertyNames[i],
new String[] { idAliases[i] }
);
subclassPropertyColumnNames.put(
ENTITY_ID + "." + getIdentifierPropertyName() + "." + idPropertyNames[i],
new String[] { idColumnNames[i] }
);
if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyName() ) ) {
subclassPropertyAliases.put(
getIdentifierPropertyName() + "." + idPropertyNames[i],
new String[] { idAliases[i] }
);
subclassPropertyColumnNames.put(
getIdentifierPropertyName() + "." + idPropertyNames[i],
new String[] { idColumnNames[i] }
);
}
else {
// embedded composite ids ( alias.idname1, alias.idname2 )
subclassPropertyAliases.put( idPropertyNames[i], new String[] { idAliases[i] } );
subclassPropertyColumnNames.put( idPropertyNames[i], new String[] { idColumnNames[i] } );
}
}
}
if ( entityMetamodel.isPolymorphic() ) {
subclassPropertyAliases.put( ENTITY_CLASS,
new String[]{getDiscriminatorAlias()} );
subclassPropertyColumnNames.put( ENTITY_CLASS,
new String[]{getDiscriminatorColumnName()} );
}
}
private void internalInitSubclassPropertyAliasesMap(String path, Iterator propertyIterator) {
while ( propertyIterator.hasNext() ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -