|
87 | 87 | import org.hibernate.internal.FilterConfiguration;
|
88 | 88 | import org.hibernate.internal.FilterHelper;
|
89 | 89 | import org.hibernate.internal.util.StringHelper;
|
| 90 | +import org.hibernate.internal.util.ValueHolder; |
90 | 91 | import org.hibernate.internal.util.collections.ArrayHelper;
|
91 | 92 | import org.hibernate.jdbc.Expectation;
|
92 | 93 | import org.hibernate.jdbc.Expectations;
|
@@ -199,6 +200,7 @@ public abstract class AbstractEntityPersister
|
199 | 200 | //information about lazy properties of this class
|
200 | 201 | private final String[] lazyPropertyNames;
|
201 | 202 | private final int[] lazyPropertyNumbers;
|
| 203 | + |
202 | 204 | private final Type[] lazyPropertyTypes;
|
203 | 205 | private final String[][] lazyPropertyColumnAliases;
|
204 | 206 |
|
@@ -266,7 +268,7 @@ public abstract class AbstractEntityPersister
|
266 | 268 | protected ExecuteUpdateResultCheckStyle[] deleteResultCheckStyles;
|
267 | 269 |
|
268 | 270 | private InsertGeneratedIdentifierDelegate identityDelegate;
|
269 |
| - |
| 271 | + private LazyPropertyInitializer lazyPropertyInitializerDelegater = new LazyPropertyInitializerImpl( this ); |
270 | 272 | private boolean[] tableHasColumns;
|
271 | 273 |
|
272 | 274 | private final String loaderName;
|
@@ -1204,149 +1206,13 @@ protected String generateLazySelectString() {
|
1204 | 1206 | ArrayHelper.toIntArray( formulaNumbers ) );
|
1205 | 1207 |
|
1206 | 1208 | }
|
1207 |
| - |
| 1209 | + @Override |
1208 | 1210 | public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session)
|
1209 | 1211 | throws HibernateException {
|
1210 |
| - |
1211 |
| - final Serializable id = session.getContextEntityIdentifier( entity ); |
1212 |
| - |
1213 |
| - final EntityEntry entry = session.getPersistenceContext().getEntry( entity ); |
1214 |
| - if ( entry == null ) { |
1215 |
| - throw new HibernateException( "entity is not associated with the session: " + id ); |
1216 |
| - } |
1217 |
| - |
1218 |
| - if ( LOG.isTraceEnabled() ) { |
1219 |
| - LOG.tracev( "Initializing lazy properties of: {0}, field access: {1}", MessageHelper.infoString( this, id, getFactory() ), fieldName ); |
1220 |
| - } |
1221 |
| - |
1222 |
| - if ( hasCache() ) { |
1223 |
| - CacheKey cacheKey = session.generateCacheKey( id, getIdentifierType(), getEntityName() ); |
1224 |
| - Object ce = getCacheAccessStrategy().get( cacheKey, session.getTimestamp() ); |
1225 |
| - if (ce!=null) { |
1226 |
| - CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory); |
1227 |
| - if ( !cacheEntry.areLazyPropertiesUnfetched() ) { |
1228 |
| - //note early exit here: |
1229 |
| - return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry ); |
1230 |
| - } |
1231 |
| - } |
1232 |
| - } |
1233 |
| - |
1234 |
| - return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry ); |
| 1212 | + return lazyPropertyInitializerDelegater.initializeLazyProperty( fieldName, entity, session ); |
1235 | 1213 |
|
1236 | 1214 | }
|
1237 | 1215 |
|
1238 |
| - private Object initializeLazyPropertiesFromDatastore( |
1239 |
| - final String fieldName, |
1240 |
| - final Object entity, |
1241 |
| - final SessionImplementor session, |
1242 |
| - final Serializable id, |
1243 |
| - final EntityEntry entry) { |
1244 |
| - |
1245 |
| - if ( !hasLazyProperties() ) { |
1246 |
| - throw new AssertionFailure( "no lazy properties" ); |
1247 |
| - } |
1248 |
| - |
1249 |
| - LOG.trace( "Initializing lazy properties from datastore" ); |
1250 |
| - |
1251 |
| - try { |
1252 |
| - |
1253 |
| - Object result = null; |
1254 |
| - PreparedStatement ps = null; |
1255 |
| - try { |
1256 |
| - final String lazySelect = getSQLLazySelectString(); |
1257 |
| - ResultSet rs = null; |
1258 |
| - try { |
1259 |
| - if ( lazySelect != null ) { |
1260 |
| - // null sql means that the only lazy properties |
1261 |
| - // are shared PK one-to-one associations which are |
1262 |
| - // handled differently in the Type#nullSafeGet code... |
1263 |
| - ps = session.getTransactionCoordinator() |
1264 |
| - .getJdbcCoordinator() |
1265 |
| - .getStatementPreparer() |
1266 |
| - .prepareStatement( lazySelect ); |
1267 |
| - getIdentifierType().nullSafeSet( ps, id, 1, session ); |
1268 |
| - rs = ps.executeQuery(); |
1269 |
| - rs.next(); |
1270 |
| - } |
1271 |
| - final Object[] snapshot = entry.getLoadedState(); |
1272 |
| - for ( int j = 0; j < lazyPropertyNames.length; j++ ) { |
1273 |
| - Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity ); |
1274 |
| - if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { |
1275 |
| - result = propValue; |
1276 |
| - } |
1277 |
| - } |
1278 |
| - } |
1279 |
| - finally { |
1280 |
| - if ( rs != null ) { |
1281 |
| - rs.close(); |
1282 |
| - } |
1283 |
| - } |
1284 |
| - } |
1285 |
| - finally { |
1286 |
| - if ( ps != null ) { |
1287 |
| - ps.close(); |
1288 |
| - } |
1289 |
| - } |
1290 |
| - |
1291 |
| - LOG.trace( "Done initializing lazy properties" ); |
1292 |
| - |
1293 |
| - return result; |
1294 |
| - |
1295 |
| - } |
1296 |
| - catch ( SQLException sqle ) { |
1297 |
| - throw getFactory().getSQLExceptionHelper().convert( |
1298 |
| - sqle, |
1299 |
| - "could not initialize lazy properties: " + |
1300 |
| - MessageHelper.infoString( this, id, getFactory() ), |
1301 |
| - getSQLLazySelectString() |
1302 |
| - ); |
1303 |
| - } |
1304 |
| - } |
1305 |
| - |
1306 |
| - private Object initializeLazyPropertiesFromCache( |
1307 |
| - final String fieldName, |
1308 |
| - final Object entity, |
1309 |
| - final SessionImplementor session, |
1310 |
| - final EntityEntry entry, |
1311 |
| - final CacheEntry cacheEntry |
1312 |
| - ) { |
1313 |
| - |
1314 |
| - LOG.trace( "Initializing lazy properties from second-level cache" ); |
1315 |
| - |
1316 |
| - Object result = null; |
1317 |
| - Serializable[] disassembledValues = cacheEntry.getDisassembledState(); |
1318 |
| - final Object[] snapshot = entry.getLoadedState(); |
1319 |
| - for ( int j = 0; j < lazyPropertyNames.length; j++ ) { |
1320 |
| - final Object propValue = lazyPropertyTypes[j].assemble( |
1321 |
| - disassembledValues[ lazyPropertyNumbers[j] ], |
1322 |
| - session, |
1323 |
| - entity |
1324 |
| - ); |
1325 |
| - if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) { |
1326 |
| - result = propValue; |
1327 |
| - } |
1328 |
| - } |
1329 |
| - |
1330 |
| - LOG.trace( "Done initializing lazy properties" ); |
1331 |
| - |
1332 |
| - return result; |
1333 |
| - } |
1334 |
| - |
1335 |
| - private boolean initializeLazyProperty( |
1336 |
| - final String fieldName, |
1337 |
| - final Object entity, |
1338 |
| - final SessionImplementor session, |
1339 |
| - final Object[] snapshot, |
1340 |
| - final int j, |
1341 |
| - final Object propValue) { |
1342 |
| - setPropertyValue( entity, lazyPropertyNumbers[j], propValue ); |
1343 |
| - if ( snapshot != null ) { |
1344 |
| - // object have been loaded with setReadOnly(true); HHH-2236 |
1345 |
| - snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, factory ); |
1346 |
| - } |
1347 |
| - return fieldName.equals( lazyPropertyNames[j] ); |
1348 |
| - } |
1349 |
| - |
1350 | 1216 | public boolean isBatchable() {
|
1351 | 1217 | return optimisticLockStyle() == OptimisticLockStyle.NONE
|
1352 | 1218 | || ( !isVersioned() && optimisticLockStyle() == OptimisticLockStyle.VERSION )
|
@@ -3014,15 +2880,23 @@ public Object getEntity() {
|
3014 | 2880 | return identityDelegate.performInsert( sql, session, binder );
|
3015 | 2881 | }
|
3016 | 2882 |
|
| 2883 | + private ValueHolder<String> identitySelectStringValue = new ValueHolder<String>( |
| 2884 | + new ValueHolder.DeferredInitializer<String>() { |
| 2885 | + @Override |
| 2886 | + public String initialize() { |
| 2887 | + return getFactory().getDialect().getIdentitySelectString( |
| 2888 | + getTableName( 0 ), |
| 2889 | + getKeyColumns( 0 )[0], |
| 2890 | + getIdentifierType().sqlTypes( getFactory() )[0] |
| 2891 | + ); |
| 2892 | + } |
| 2893 | + } |
| 2894 | + ); |
| 2895 | + @Override |
3017 | 2896 | public String getIdentitySelectString() {
|
3018 |
| - //TODO: cache this in an instvar |
3019 |
| - return getFactory().getDialect().getIdentitySelectString( |
3020 |
| - getTableName(0), |
3021 |
| - getKeyColumns(0)[0], |
3022 |
| - getIdentifierType().sqlTypes( getFactory() )[0] |
3023 |
| - ); |
| 2897 | + return identitySelectStringValue.getValue(); |
3024 | 2898 | }
|
3025 |
| - |
| 2899 | + @Override |
3026 | 2900 | public String getSelectByUniqueKeyString(String propertyName) {
|
3027 | 2901 | return new SimpleSelect( getFactory().getDialect() )
|
3028 | 2902 | .setTableName( getTableName(0) )
|
@@ -5024,5 +4898,21 @@ public String getTableAliasForColumn(String columnName, String rootAlias) {
|
5024 | 4898 | public int determineTableNumberForColumn(String columnName) {
|
5025 | 4899 | return 0;
|
5026 | 4900 | }
|
5027 |
| - |
| 4901 | + |
| 4902 | + |
| 4903 | + Type[] getLazyPropertyTypes() { |
| 4904 | + return lazyPropertyTypes; |
| 4905 | + } |
| 4906 | + |
| 4907 | + int[] getLazyPropertyNumbers() { |
| 4908 | + return lazyPropertyNumbers; |
| 4909 | + } |
| 4910 | + |
| 4911 | + String[] getLazyPropertyNames() { |
| 4912 | + return lazyPropertyNames; |
| 4913 | + } |
| 4914 | + |
| 4915 | + String[][] getLazyPropertyColumnAliases() { |
| 4916 | + return lazyPropertyColumnAliases; |
| 4917 | + } |
5028 | 4918 | }
|
0 commit comments