Skip to content

Commit

Permalink
#414 - Hibernate 4.2 fixes and avoid unnecessary model lookups
Browse files Browse the repository at this point in the history
  • Loading branch information
beikov committed Nov 6, 2017
1 parent 6f7f64a commit a893a82
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.blazebit.persistence.impl.util.JpaMetamodelUtils;
import com.blazebit.persistence.view.CascadeType;
import com.blazebit.persistence.view.InverseRemoveStrategy;
import com.blazebit.persistence.view.Mapping;
import com.blazebit.persistence.view.MappingCorrelated;
import com.blazebit.persistence.view.MappingCorrelatedSimple;
import com.blazebit.persistence.view.MappingParameter;
Expand Down Expand Up @@ -236,6 +235,8 @@ public String determineMappedBy(ManagedType<?> managedType, String mapping, Meta
return mappedBy;
}

mappedByResolved = true;

if (mapping.isEmpty()) {
return null;
}
Expand All @@ -261,7 +262,7 @@ public String determineMappedBy(ManagedType<?> managedType, String mapping, Meta
return null;
}
}
return context.getJpaProvider().getMappedBy((EntityType<?>) managedType, mapping);
return mappedBy = context.getJpaProvider().getMappedBy((EntityType<?>) managedType, mapping);
} catch (IllegalArgumentException ex) {
// if the mapping is invalid, we skip the determination as the error will be analyzed further at a later stage
return null;
Expand Down Expand Up @@ -369,12 +370,6 @@ private static String methodReference(Method method) {
return (AbstractMethodAttribute<? super X, ?>) attribute;
}

if (!mappedByResolved && mapping instanceof Mapping) {
ManagedType<?> managedType = context.getEntityMetamodel().getManagedType(viewType.getEntityClass());
mappedBy = determineMappedBy(managedType, AbstractAttribute.stripThisFromMapping(((Mapping) mapping).value()), context);
}
mappedByResolved = true;

boolean correlated = mapping instanceof MappingCorrelated || mapping instanceof MappingCorrelatedSimple;

if (isCollection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,25 +115,25 @@ public MutableBasicUserTypeRegistry() {

// NOTE: keep this in sync with 09_basic_user_type.adoc

Map<Class<?>, TypeConverter<?, ?>> map = new HashMap<>();
map.put(Blob.class, BlobTypeConverter.INSTANCE);
converters.put(Blob.class, map);
map = new HashMap<>();
map.put(Clob.class, ClobTypeConverter.INSTANCE);
converters.put(Clob.class, map);
map = new HashMap<>();
map.put(NClob.class, NClobTypeConverter.INSTANCE);
converters.put(NClob.class, map);

// Java 8 optional types
try {
Map<Class<?>, TypeConverter<?, ?>> map = new HashMap<>();
map = new HashMap<>();
map.put(Object.class, new OptionalTypeConverter());
converters.put(Class.forName("java.util.Optional"), map);
// TODO: OptionalInt etc.
map = new HashMap<>();
map.put(Blob.class, BlobTypeConverter.INSTANCE);
converters.put(Blob.class, map);
map = new HashMap<>();
map.put(Clob.class, ClobTypeConverter.INSTANCE);
converters.put(Clob.class, map);
map = new HashMap<>();
map.put(NClob.class, NClobTypeConverter.INSTANCE);
converters.put(NClob.class, map);
} catch (ClassNotFoundException ex) {
// If they aren't found, we ignore them
}

}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ public void addRecordingMap(RecordingMap<?, ?, ?> recordingMap, List<? extends M
coalescedRecordingActions.add(removedElements);
}


@Override
public void addPersistedView(MutableStateTrackable persistedView) {
if (persistedViews == null) {
Expand Down Expand Up @@ -146,7 +145,6 @@ public void afterCompletion(int status) {
for (int i = 0; i < persistedViews.size(); i += 2) {
MutableStateTrackable view = (MutableStateTrackable) persistedViews.get(i);
view.$$_setIsNew(true);
view.$$_setId(null);
view.$$_setDirty((long[]) persistedViews.get(i + 1));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,11 @@
import com.blazebit.persistence.view.FlushMode;
import com.blazebit.persistence.view.FlushStrategy;
import com.blazebit.persistence.view.spi.EntityViewConfiguration;
import com.blazebit.persistence.view.testsuite.basic.model.IntIdEntityView;
import com.blazebit.persistence.view.testsuite.entity.LegacyOrder;
import com.blazebit.persistence.view.testsuite.entity.LegacyOrderPosition;
import com.blazebit.persistence.view.testsuite.entity.LegacyOrderPositionDefault;
import com.blazebit.persistence.view.testsuite.entity.LegacyOrderPositionDefaultId;
import com.blazebit.persistence.view.testsuite.entity.LegacyOrderPositionId;
import com.blazebit.persistence.view.testsuite.proxy.model.EmbeddableTestEntityView;
import com.blazebit.persistence.view.testsuite.proxy.model.UpdatableEmbeddableTestEntityNestedEmbeddableView;
import com.blazebit.persistence.view.testsuite.proxy.model.UpdatableNameObjectView;
import com.blazebit.persistence.view.testsuite.update.AbstractEntityViewUpdateTest;
import com.blazebit.persistence.view.testsuite.update.subview.inverse.model.LegacyOrderIdView;
import com.blazebit.persistence.view.testsuite.update.subview.inverse.model.LegacyOrderPositionDefaultIdView;
Expand All @@ -41,7 +37,6 @@
import com.blazebit.persistence.view.testsuite.update.subview.inverse.model.UpdatableLegacyOrderPositionView;
import com.blazebit.persistence.view.testsuite.update.subview.inverse.model.UpdatableLegacyOrderView;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
Expand Down Expand Up @@ -103,7 +98,6 @@ public void testAddNewElementToCollection() {
}

@Test
@Ignore("Persisting elements with inverse elements only supported when flush operation queuing is implemented!")
public void testPersistAndAddNewElementToCollection() {
UpdatableLegacyOrderView newOrder = evm.create(UpdatableLegacyOrderView.class);
UpdatableLegacyOrderPositionView position = evm.create(UpdatableLegacyOrderPositionView.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.loader.collection.CollectionInitializer;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.ToOne;
import org.hibernate.persister.collection.BasicCollectionPersister;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* @author Jan-Willem Gmelig Meyling
* @since 1.2.0
Expand All @@ -37,7 +45,48 @@ public class CustomBasicCollectionPersister extends BasicCollectionPersister imp

public CustomBasicCollectionPersister(Collection collection, CollectionRegionAccessStrategy cacheAccessStrategy, Configuration cfg, SessionFactoryImplementor factory) throws MappingException, CacheException {
super(collection, cacheAccessStrategy, cfg, factory);
this.mappedByProperty = collection.getReferencedPropertyName();
String referencedPropertyName = collection.getReferencedPropertyName();
if (referencedPropertyName == null && collection.isInverse()) {
referencedPropertyName = findMappedByProperty(collection);
}
this.mappedByProperty = referencedPropertyName;
}

@SuppressWarnings("unchecked")
private String findMappedByProperty(Collection collection) {
String ownerEntityName = collection.getOwnerEntityName();
Iterator<Column> columnIterator = collection.getKey().getColumnIterator();
List<String> columnNames = new ArrayList<>();
while (columnIterator.hasNext()) {
Column column = columnIterator.next();
columnNames.add(column.getName());
}

OneToMany oneToMany = (OneToMany) collection.getElement();
Iterator propertyIterator = oneToMany.getAssociatedClass().getPropertyIterator();
while (propertyIterator.hasNext()) {
Property property = (Property) propertyIterator.next();
if (property.getValue() instanceof ToOne) {
ToOne toOne = (ToOne) property.getValue();
if (ownerEntityName.equals(toOne.getReferencedEntityName())
&& matches(columnNames, collection.getKey().getColumnIterator())) {
return property.getName();
}
}
}

return null;
}

private boolean matches(List<String> columns, Iterator<Column> iter) {
for (int i = 0; iter.hasNext(); i++) {
Column column = iter.next();
if (i == columns.size() || !columns.get(i).equals(column.getName())) {
return false;
}
}

return true;
}

@Override
Expand All @@ -49,7 +98,7 @@ public String getMappedByProperty() {
protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) {
// Hibernate before 4 couldn't find the correct from clause
StringBuilder sb = null;
String subselectQuery = subselect.toSubselectString( getCollectionType().getLHSPropertyName() );
String subselectQuery = subselect.toSubselectString(getCollectionType().getLHSPropertyName());
int parens = 0;

for (int i = 0; i < subselectQuery.length(); i++) {
Expand All @@ -75,13 +124,13 @@ protected CollectionInitializer createSubselectInitializer(SubselectFetch subsel
}

return new CustomSubselectCollectionLoader(
this,
subselectQuery,
subselect.getResult(),
subselect.getQueryParameters(),
subselect.getNamedParameterLocMap(),
session.getFactory(),
session.getLoadQueryInfluencers()
this,
subselectQuery,
subselect.getResult(),
subselect.getQueryParameters(),
subselect.getNamedParameterLocMap(),
session.getFactory(),
session.getLoadQueryInfluencers()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@
import org.hibernate.engine.spi.SubselectFetch;
import org.hibernate.loader.collection.CollectionInitializer;
import org.hibernate.mapping.Collection;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.ToOne;
import org.hibernate.persister.collection.OneToManyPersister;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
*
* @author Christian Beikov
Expand All @@ -38,7 +46,48 @@ public class CustomOneToManyPersister extends OneToManyPersister implements Cust

public CustomOneToManyPersister(Collection collection, CollectionRegionAccessStrategy cacheAccessStrategy, Configuration cfg, SessionFactoryImplementor factory) throws MappingException, CacheException {
super(collection, cacheAccessStrategy, cfg, factory);
this.mappedByProperty = collection.getReferencedPropertyName();
String referencedPropertyName = collection.getReferencedPropertyName();
if (referencedPropertyName == null && collection.isInverse()) {
referencedPropertyName = findMappedByProperty(collection);
}
this.mappedByProperty = referencedPropertyName;
}

@SuppressWarnings("unchecked")
private String findMappedByProperty(Collection collection) {
String ownerEntityName = collection.getOwnerEntityName();
Iterator<Column> columnIterator = collection.getKey().getColumnIterator();
List<String> columnNames = new ArrayList<>();
while (columnIterator.hasNext()) {
Column column = columnIterator.next();
columnNames.add(column.getName());
}

OneToMany oneToMany = (OneToMany) collection.getElement();
Iterator propertyIterator = oneToMany.getAssociatedClass().getPropertyIterator();
while (propertyIterator.hasNext()) {
Property property = (Property) propertyIterator.next();
if (property.getValue() instanceof ToOne) {
ToOne toOne = (ToOne) property.getValue();
if (ownerEntityName.equals(toOne.getReferencedEntityName())
&& matches(columnNames, collection.getKey().getColumnIterator())) {
return property.getName();
}
}
}

return null;
}

private boolean matches(List<String> columns, Iterator<Column> iter) {
for (int i = 0; iter.hasNext(); i++) {
Column column = iter.next();
if (i == columns.size() || !columns.get(i).equals(column.getName())) {
return false;
}
}

return true;
}

@Override
Expand Down

0 comments on commit a893a82

Please sign in to comment.