use of com.blazebit.persistence.spi.JpaProvider in project blaze-persistence by Blazebit.
the class EntityViewUpdaterImpl method createPluralAttributeFlusher.
private DirtyAttributeFlusher<?, ?, ?> createPluralAttributeFlusher(EntityViewManagerImpl evm, Map<Object, EntityViewUpdaterImpl> localCache, ManagedViewTypeImplementor<?> viewType, String idAttributeName, FlushStrategy flushStrategy, AbstractMethodAttribute<?, ?> attribute, DirtyAttributeFlusher<?, ?, ?> ownerIdFlusher, EntityViewUpdaterImpl owner, String ownerMapping) {
EntityMetamodel entityMetamodel = evm.getMetamodel().getEntityMetamodel();
Class<?> entityClass = viewType.getEntityClass();
ExtendedManagedType managedType = entityMetamodel.getManagedType(ExtendedManagedType.class, entityClass);
String attributeName = attribute.getName();
String attributeMapping = attribute.getMapping();
AttributeAccessor entityAttributeAccessor = Accessors.forEntityMapping(evm, attribute);
boolean cascadeDelete = attribute.isDeleteCascaded();
boolean viewOnlyDeleteCascaded = cascadeDelete && !managedType.getAttribute(attributeMapping).isDeleteCascaded();
boolean optimisticLockProtected = attribute.isOptimisticLockProtected();
JpaProvider jpaProvider = evm.getJpaProvider();
PluralAttribute<?, ?, ?> pluralAttribute = (PluralAttribute<?, ?, ?>) attribute;
InitialValueAttributeAccessor viewAttributeAccessor = Accessors.forMutableViewAttribute(evm, attribute);
ManagedType<?> ownerManagedType = owner == null ? viewType.getJpaManagedType() : owner.managedViewType.getJpaManagedType();
EntityType<?> ownerEntityType = ownerManagedType instanceof EntityType<?> ? (EntityType<?>) ownerManagedType : null;
DirtyAttributeFlusher<?, ?, ?> attributeOwnerFlusher;
if (attributeMapping == null || ownerEntityType == null) {
// In case of cascading only attributes i.e. correlations, we use the owner id flusher as it's not updatable anyway
attributeOwnerFlusher = ownerIdFlusher;
} else {
Map<String, String> joinTableOwnerProperties;
if (ownerMapping == null) {
joinTableOwnerProperties = jpaProvider.getJoinMappingPropertyNames(ownerEntityType, ownerMapping, attributeMapping);
} else {
joinTableOwnerProperties = jpaProvider.getJoinMappingPropertyNames(ownerEntityType, ownerMapping, ownerMapping + "." + attributeMapping);
}
if (joinTableOwnerProperties.size() != 1) {
String idMapping = ownerIdFlusher.getMapping();
String prefix;
if (idMapping.endsWith(".")) {
prefix = idMapping;
} else {
prefix = idMapping + ".";
}
for (String joinTableOwnerProperty : joinTableOwnerProperties.keySet()) {
if (!joinTableOwnerProperty.startsWith(prefix)) {
throw new IllegalArgumentException("Multiple joinable owner properties for attribute '" + attributeName + "' of " + ownerEntityType.getJavaType().getName() + " found which is not yet supported. Consider using the primary key instead!");
}
}
attributeOwnerFlusher = ownerIdFlusher;
} else if (ownerIdFlusher.getMapping().equals(joinTableOwnerProperties.values().iterator().next())) {
attributeOwnerFlusher = ownerIdFlusher;
} else {
attributeOwnerFlusher = findSingularAttributeFlusherByMapping(evm, localCache, owner, viewType, attributeName, joinTableOwnerProperties.keySet().iterator().next());
}
}
TypeDescriptor elementDescriptor = TypeDescriptor.forType(evm, localCache, this, attribute, pluralAttribute.getElementType(), owner, ownerMapping);
boolean collectionUpdatable = attribute.isUpdatable();
CollectionRemoveListener elementRemoveListener = createOrphanRemoveListener(attribute, elementDescriptor);
CollectionRemoveListener elementCascadeDeleteListener = createCascadeDeleteListener(attribute, elementDescriptor);
boolean jpaProviderDeletesCollection;
boolean supportsCollectionDml = jpaProvider.supportsInsertStatement();
if (elementDescriptor.getAttributeIdAttributeName() != null) {
jpaProviderDeletesCollection = jpaProvider.supportsJoinTableCleanupOnDelete();
} else {
jpaProviderDeletesCollection = jpaProvider.supportsCollectionTableCleanupOnDelete();
}
if (attribute instanceof MapAttribute<?, ?, ?>) {
MapAttribute<?, ?, ?> mapAttribute = (MapAttribute<?, ?, ?>) attribute;
TypeDescriptor keyDescriptor = TypeDescriptor.forType(evm, localCache, this, attribute, mapAttribute.getKeyType(), owner, ownerMapping);
// TODO: currently there is no possibility to set this
CollectionRemoveListener keyRemoveListener = null;
CollectionRemoveListener keyCascadeDeleteListener = null;
if (collectionUpdatable || keyDescriptor.shouldFlushMutations() || elementDescriptor.shouldFlushMutations() || shouldPassThrough(evm, viewType, attribute)) {
MapViewToEntityMapper mapper = new SimpleMapViewToEntityMapper(keyDescriptor.getViewToEntityMapper(), elementDescriptor.getViewToEntityMapper());
MapViewToEntityMapper loadOnlyMapper = new SimpleMapViewToEntityMapper(keyDescriptor.getLoadOnlyViewToEntityMapper(), elementDescriptor.getLoadOnlyViewToEntityMapper());
MapInstantiatorImplementor<?, ?> mapInstantiator = attribute.getMapInstantiator();
return new MapAttributeFlusher<Object, RecordingMap<Map<?, ?>, ?, ?>>(attributeName, attributeMapping, owner == null ? entityClass : owner.fullEntityLoader.getEntityClass(), idAttributeName, ownerMapping, attributeOwnerFlusher, createPluralAttributeSubFlusher(evm, localCache, viewType, attribute, "element", mapAttribute.getElementType(), owner, ownerMapping), supportsCollectionDml, flushStrategy, entityAttributeAccessor, viewAttributeAccessor, optimisticLockProtected, collectionUpdatable, keyCascadeDeleteListener, elementCascadeDeleteListener, keyRemoveListener, elementRemoveListener, viewOnlyDeleteCascaded, jpaProviderDeletesCollection, keyDescriptor, elementDescriptor, mapper, loadOnlyMapper, mapInstantiator);
} else {
return null;
}
} else {
if (collectionUpdatable || elementDescriptor.shouldFlushMutations() || shouldPassThrough(evm, viewType, attribute)) {
InverseFlusher<Object> inverseFlusher = InverseFlusher.forAttribute(evm, localCache, viewType, attribute, elementDescriptor, owner, ownerMapping);
InverseRemoveStrategy inverseRemoveStrategy = attribute.getInverseRemoveStrategy();
CollectionInstantiatorImplementor<?, ?> collectionInstantiator = attribute.getCollectionInstantiator();
if (pluralAttribute.isIndexed()) {
return new IndexedListAttributeFlusher<Object, RecordingList<List<?>>>(attributeName, attributeMapping, owner == null ? entityClass : owner.fullEntityLoader.getEntityClass(), idAttributeName, ownerMapping, attributeOwnerFlusher, createPluralAttributeSubFlusher(evm, localCache, viewType, attribute, "element", pluralAttribute.getElementType(), owner, ownerMapping), supportsCollectionDml, flushStrategy, entityAttributeAccessor, viewAttributeAccessor, optimisticLockProtected, collectionUpdatable, viewOnlyDeleteCascaded, jpaProviderDeletesCollection, elementCascadeDeleteListener, elementRemoveListener, collectionInstantiator, elementDescriptor, inverseFlusher, inverseRemoveStrategy);
} else {
return new CollectionAttributeFlusher(attributeName, attributeMapping, owner == null ? entityClass : owner.fullEntityLoader.getEntityClass(), idAttributeName, ownerMapping, attributeOwnerFlusher, createPluralAttributeSubFlusher(evm, localCache, viewType, attribute, "element", pluralAttribute.getElementType(), owner, ownerMapping), supportsCollectionDml, flushStrategy, entityAttributeAccessor, viewAttributeAccessor, optimisticLockProtected, collectionUpdatable, viewOnlyDeleteCascaded, jpaProviderDeletesCollection, elementCascadeDeleteListener, elementRemoveListener, collectionInstantiator, elementDescriptor, inverseFlusher, inverseRemoveStrategy);
}
} else {
return null;
}
}
}
use of com.blazebit.persistence.spi.JpaProvider in project blaze-persistence by Blazebit.
the class AbstractJpaPersistenceTest method init.
@Before
public void init() {
boolean firstTest = lastTestClass != getClass();
boolean veryFirstTest = lastTestClass == null;
boolean schemaChanged;
lastTestClass = getClass();
// If a previous test run resolved the no-op cleaner, we won't be able to resolve any other cleaner
if (resolvedNoop) {
databaseCleaner = null;
schemaChanged = true;
} else {
databaseCleaner = getLastDatabaseCleaner();
schemaChanged = databaseCleaner == null || !Objects.equals(lastTargetSchema, getTargetSchema());
}
lastTargetSchema = getTargetSchema();
SchemaMode schemaMode = getSchemaMode();
if (dataSource != null && lastSchemaMode != schemaMode) {
dataSource.close();
dataSource = null;
closeEmf();
}
lastSchemaMode = schemaMode;
// Nothing to delete if the schema changed
databaseClean = schemaChanged;
if (dataSource != null && recreateDataSource()) {
recreateTestClass = getClass();
dataSource.close();
dataSource = null;
closeEmf();
} else if (recreateTestClass != null && recreateTestClass != getClass()) {
recreateTestClass = null;
if (dataSource != null) {
dataSource.close();
dataSource = null;
}
closeEmf();
}
// Disable query collecting
QueryInspectorListener.enabled = false;
QueryInspectorListener.collectSequences = false;
if (!resolvedNoop && databaseCleaner == null) {
if (bootstrapDataSource == null) {
getBootstrapDataSource();
}
try (Connection c = bootstrapDataSource.getConnection()) {
DatabaseCleaner applicableCleaner = getDatabaseCleaner(c);
if (applicableCleaner == null) {
// If none was found, we use the default cleaner
Logger.getLogger(getClass().getName()).warning("Could not resolve database cleaner for the database, falling back to drop-and-create strategy.");
resolvedNoop = true;
}
String targetDatabase = getTargetDatabase();
String targetSchema = getTargetSchema();
if (targetDatabase != null) {
databaseCleaner.createDatabaseIfNotExists(c, targetDatabase);
}
if (targetSchema != null) {
createSchemaIfNotExists(c, targetSchema);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (databaseCleaner == null) {
// The default cleaner which recreates the schema
setLastDatabaseCleaner(getDefaultDatabaseCleaner());
}
EntityManagerFactory emfBefore = emf;
if (veryFirstTest || schemaChanged) {
getDataSource(createProperties("none"));
emf = repopulateSchema();
if (emf == null) {
emf = createEntityManagerFactory("TestsuiteBase", createProperties("none"));
}
} else if (emf == null || !emf.isOpen()) {
emf = createEntityManagerFactory("TestsuiteBase", createProperties("none"));
}
if (activeCriteriaBuilderConfiguration == null) {
if (requiresCriteriaBuilderConfigurationCustomization()) {
activeCriteriaBuilderConfiguration = Criteria.getDefault();
configure(activeCriteriaBuilderConfiguration);
} else {
if (defaultCbConfiguration == null) {
// We cannot initialize this statically due to static initializer in
// com.blazebit.persistence.testsuite.base.AbstractPersistenceTest (Hibernate)
defaultCbConfiguration = Criteria.getDefault();
}
activeCriteriaBuilderConfiguration = defaultCbConfiguration;
}
}
CriteriaBuilderConfigurationEqualityWrapper cfgEqualityWrapper = new CriteriaBuilderConfigurationEqualityWrapper((CriteriaBuilderConfigurationImpl) activeCriteriaBuilderConfiguration);
if (cbf == null || emfBefore != emf || !cfgEqualityWrapper.equals(lastCriteriaBuilderConfigurationEqualityWrapper)) {
cbf = activeCriteriaBuilderConfiguration.createCriteriaBuilderFactory(emf);
lastCriteriaBuilderConfigurationEqualityWrapper = cfgEqualityWrapper;
jpaProvider = cbf.getService(JpaProvider.class);
dbmsDialect = cbf.getService(DbmsDialect.class);
}
getEm();
if (firstTest) {
setUpOnce();
}
if (runTestInTransaction() && !getEm().getTransaction().isActive()) {
getEm().getTransaction().begin();
}
}
Aggregations