use of org.hibernate.loader.ast.internal.SingleIdArrayLoadPlan in project hibernate-orm by hibernate.
the class AbstractEntityPersister method initializeLazyPropertiesFromDatastore.
protected Object initializeLazyPropertiesFromDatastore(final Object entity, final Object id, final EntityEntry entry, final String fieldName, final SharedSessionContractImplementor session) {
if (!hasLazyProperties()) {
throw new AssertionFailure("no lazy properties");
}
final PersistentAttributeInterceptor interceptor = ((PersistentAttributeInterceptable) entity).$$_hibernate_getInterceptor();
assert interceptor != null : "Expecting bytecode interceptor to be non-null";
LOG.tracef("Initializing lazy properties from datastore (triggered for `%s`)", fieldName);
final String fetchGroup = getEntityMetamodel().getBytecodeEnhancementMetadata().getLazyAttributesMetadata().getFetchGroupName(fieldName);
final List<LazyAttributeDescriptor> fetchGroupAttributeDescriptors = getEntityMetamodel().getBytecodeEnhancementMetadata().getLazyAttributesMetadata().getFetchGroupAttributeDescriptors(fetchGroup);
final Set<String> initializedLazyAttributeNames = interceptor.getInitializedLazyAttributeNames();
final SingleIdArrayLoadPlan lazySelect = getSQLLazySelectLoadPlan(fetchGroup);
try {
Object result = null;
final Object[] values = lazySelect.load(id, session);
int i = 0;
for (LazyAttributeDescriptor fetchGroupAttributeDescriptor : fetchGroupAttributeDescriptors) {
final boolean previousInitialized = initializedLazyAttributeNames.contains(fetchGroupAttributeDescriptor.getName());
if (previousInitialized) {
// todo : one thing we should consider here is potentially un-marking an attribute as dirty based on the selected value
// we know the current value - getPropertyValue( entity, fetchGroupAttributeDescriptor.getAttributeIndex() );
// we know the selected value (see selectedValue below)
// we can use the attribute Type to tell us if they are the same
//
// assuming entity is a SelfDirtinessTracker we can also know if the attribute is
// currently considered dirty, and if really not dirty we would do the un-marking
//
// of course that would mean a new method on SelfDirtinessTracker to allow un-marking
// its already been initialized (e.g. by a write) so we don't want to overwrite
i++;
continue;
}
final Object selectedValue = values[i++];
final boolean set = initializeLazyProperty(fieldName, entity, entry, fetchGroupAttributeDescriptor.getLazyIndex(), selectedValue);
if (set) {
result = selectedValue;
interceptor.attributeInitialized(fetchGroupAttributeDescriptor.getName());
}
}
LOG.trace("Done initializing lazy properties");
return result;
} catch (JDBCException ex) {
throw session.getJdbcServices().getSqlExceptionHelper().convert(ex.getSQLException(), "could not initialize lazy properties: " + MessageHelper.infoString(this, id, getFactory()), lazySelect.getJdbcSelect().getSql());
}
}
use of org.hibernate.loader.ast.internal.SingleIdArrayLoadPlan in project hibernate-orm by hibernate.
the class AbstractEntityPersister method generateLazySelectStringsByFetchGroup.
protected Map<String, SingleIdArrayLoadPlan> generateLazySelectStringsByFetchGroup() {
final BytecodeEnhancementMetadata enhancementMetadata = entityMetamodel.getBytecodeEnhancementMetadata();
if (!enhancementMetadata.isEnhancedForLazyLoading() || !enhancementMetadata.getLazyAttributesMetadata().hasLazyAttributes()) {
return Collections.emptyMap();
}
Map<String, SingleIdArrayLoadPlan> result = new HashMap<>();
final LazyAttributesMetadata lazyAttributesMetadata = enhancementMetadata.getLazyAttributesMetadata();
for (String groupName : lazyAttributesMetadata.getFetchGroupNames()) {
final List<LazyAttributeDescriptor> fetchGroupAttributeDescriptors = lazyAttributesMetadata.getFetchGroupAttributeDescriptors(groupName);
final List<ModelPart> partsToSelect = new ArrayList<>(fetchGroupAttributeDescriptors.size());
for (LazyAttributeDescriptor lazyAttributeDescriptor : fetchGroupAttributeDescriptors) {
// all this only really needs to consider properties
// of this class, not its subclasses, but since we
// are reusing code used for sequential selects, we
// use the subclass closure
partsToSelect.add(getAttributeMappings().get(getSubclassPropertyIndex(lazyAttributeDescriptor.getName())));
}
if (partsToSelect.isEmpty()) {
// only one-to-one is lazily fetched
continue;
}
final List<JdbcParameter> jdbcParameters = new ArrayList<>();
final SelectStatement sqlAst = LoaderSelectBuilder.createSelect(this, partsToSelect, getIdentifierMapping(), null, 1, LoadQueryInfluencers.NONE, LockOptions.NONE, jdbcParameters::add, factory);
result.put(groupName, new SingleIdArrayLoadPlan(getIdentifierMapping(), sqlAst, jdbcParameters, LockOptions.NONE, factory));
}
return result;
}
Aggregations