Skip to content

Commit

Permalink
HHH-7167 - The new natural id code introduced in 4.1.1 depends on the…
Browse files Browse the repository at this point in the history
… order the entity persisters are loaded which leads to fatal errors
  • Loading branch information
sebersole committed Mar 14, 2012
1 parent c7afef5 commit 77393f7
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 29 deletions.
Expand Up @@ -223,8 +223,6 @@ public abstract class AbstractEntityPersister
private final Map loaders = new HashMap();

// SQL strings
private String sqlEntityIdByNaturalIdString;

private String sqlVersionSelectString;
private String sqlSnapshotSelectString;
private String sqlLazySelectString;
Expand Down Expand Up @@ -3377,26 +3375,37 @@ private String[] generateSQLDeletStrings(Object[] loadedState) {
}

protected void logStaticSQL() {
if (LOG.isDebugEnabled()) {
LOG.debugf("Static SQL for entity: %s", getEntityName());
if (sqlLazySelectString != null) LOG.debugf(" Lazy select: %s", sqlLazySelectString);
if (sqlVersionSelectString != null) LOG.debugf(" Version select: %s", sqlVersionSelectString);
if (sqlSnapshotSelectString != null) LOG.debugf(" Snapshot select: %s", sqlSnapshotSelectString);
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Static SQL for entity: %s", getEntityName() );
if ( sqlLazySelectString != null ) {
LOG.debugf( " Lazy select: %s", sqlLazySelectString );
}
if ( sqlVersionSelectString != null ) {
LOG.debugf( " Version select: %s", sqlVersionSelectString );
}
if ( sqlSnapshotSelectString != null ) {
LOG.debugf( " Snapshot select: %s", sqlSnapshotSelectString );
}
for ( int j = 0; j < getTableSpan(); j++ ) {
LOG.debugf(" Insert %s: %s", j, getSQLInsertStrings()[j]);
LOG.debugf(" Update %s: %s", j, getSQLUpdateStrings()[j]);
LOG.debugf(" Delete %s: %s", j, getSQLDeleteStrings()[j]);
LOG.debugf( " Insert %s: %s", j, getSQLInsertStrings()[j] );
LOG.debugf( " Update %s: %s", j, getSQLUpdateStrings()[j] );
LOG.debugf( " Delete %s: %s", j, getSQLDeleteStrings()[j] );
}
if ( sqlIdentityInsertString != null ) {
LOG.debugf( " Identity insert: %s", sqlIdentityInsertString );
}
if ( sqlUpdateByRowIdString != null ) {
LOG.debugf( " Update by row id (all fields): %s", sqlUpdateByRowIdString );
}
if ( sqlLazyUpdateByRowIdString != null ) {
LOG.debugf( " Update by row id (non-lazy fields): %s", sqlLazyUpdateByRowIdString );
}
if ( sqlInsertGeneratedValuesSelectString != null ) {
LOG.debugf( " Insert-generated property select: %s", sqlInsertGeneratedValuesSelectString );
}
if ( sqlUpdateGeneratedValuesSelectString != null ) {
LOG.debugf( " Update-generated property select: %s", sqlUpdateGeneratedValuesSelectString );
}
if (sqlIdentityInsertString != null) LOG.debugf(" Identity insert: %s", sqlIdentityInsertString);
if (sqlUpdateByRowIdString != null) LOG.debugf(" Update by row id (all fields): %s", sqlUpdateByRowIdString);
if (sqlLazyUpdateByRowIdString != null) LOG.debugf(" Update by row id (non-lazy fields): %s",
sqlLazyUpdateByRowIdString);
if (sqlInsertGeneratedValuesSelectString != null) LOG.debugf("Insert-generated property select: %s",
sqlInsertGeneratedValuesSelectString);
if (sqlUpdateGeneratedValuesSelectString != null) LOG.debugf("Update-generated property select: %s",
sqlUpdateGeneratedValuesSelectString);
if (sqlEntityIdByNaturalIdString != null) LOG.debugf("Id by Natural Id: %s",
sqlEntityIdByNaturalIdString);
}
}

Expand Down Expand Up @@ -3604,10 +3613,6 @@ protected void postConstruct(Mapping mapping) throws MappingException {
}

public void postInstantiate() throws MappingException {
if ( hasNaturalIdentifier() ) {
sqlEntityIdByNaturalIdString = generateEntityIdByNaturalIdSql();
}

createLoaders();
createUniqueKeyLoaders();
createQueryLoader();
Expand Down Expand Up @@ -4512,7 +4517,7 @@ public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor
);
}
}

@Override
public Serializable loadEntityIdByNaturalId(
Object[] naturalIdValues,
Expand All @@ -4526,6 +4531,8 @@ public Serializable loadEntityIdByNaturalId(
);
}

final String sqlEntityIdByNaturalIdString = determinePkByNaturalIdQuery();

try {
PreparedStatement ps = session.getTransactionCoordinator()
.getJdbcCoordinator()
Expand All @@ -4546,7 +4553,6 @@ public Serializable loadEntityIdByNaturalId(
return null;
}

// entity ID has to be serializable right?
return (Serializable) getIdentifierType().hydrate( rs, getIdentifierAliases(), session, null );
}
finally {
Expand All @@ -4570,11 +4576,24 @@ public Serializable loadEntityIdByNaturalId(
}
}

private String pkByNaturalIdQuery;

private String determinePkByNaturalIdQuery() {
if ( ! hasNaturalIdentifier() ) {
throw new HibernateException( "Attempt to build natural-id -> PK resolution query for entity that does not define natural id" );
}

if ( pkByNaturalIdQuery == null ) {
pkByNaturalIdQuery = generateEntityIdByNaturalIdSql();
}
return pkByNaturalIdQuery;
}

private String generateEntityIdByNaturalIdSql() {
EntityPersister rootPersister = getFactory().getEntityPersister( getRootEntityName() );
if ( rootPersister != this ) {
if ( rootPersister instanceof AbstractEntityPersister ) {
return ( (AbstractEntityPersister) rootPersister ).sqlEntityIdByNaturalIdString;
return ( (AbstractEntityPersister) rootPersister ).generateEntityIdByNaturalIdSql();
}
}

Expand Down
Expand Up @@ -117,21 +117,22 @@ public void testManyToOneNaturalIdCached() {
stats.clear();
assertEquals( "NaturalId cache puts should be zero", 0, stats.getNaturalIdCachePutCount() );
assertEquals( "NaturalId cache hits should be zero", 0, stats.getNaturalIdCacheHitCount() );
assertEquals( "NaturalId Cache Puts", 0, stats.getNaturalIdCachePutCount() );
assertEquals( "NaturalId cache misses should be zero", 0, stats.getNaturalIdCacheMissCount() );

// first query
List results = criteria.list();
assertEquals( 1, results.size() );
assertEquals( "NaturalId Cache Hits", 0, stats.getNaturalIdCacheHitCount() );
assertEquals( "NaturalId Cache Misses", 1, stats.getNaturalIdCacheMissCount() );
assertEquals( "NaturalId Cache Puts", 1, stats.getNaturalIdCachePutCount() );
assertEquals( "NaturalId Cache Puts", 2, stats.getNaturalIdCachePutCount() ); // one for Citizen, one for NaturalIdOnManyToOne
assertEquals( "NaturalId Cache Queries", 1, stats.getNaturalIdQueryExecutionCount() );

// query a second time - result should be in session cache
criteria.list();
assertEquals( "NaturalId Cache Hits", 0, stats.getNaturalIdCacheHitCount() );
assertEquals( "NaturalId Cache Misses", 1, stats.getNaturalIdCacheMissCount() );
assertEquals( "NaturalId Cache Puts", 1, stats.getNaturalIdCachePutCount() );
assertEquals( "NaturalId Cache Puts", 2, stats.getNaturalIdCachePutCount() );
assertEquals( "NaturalId Cache Queries", 1, stats.getNaturalIdQueryExecutionCount() );

// cleanup
Expand Down

0 comments on commit 77393f7

Please sign in to comment.