Skip to content

Commit

Permalink
another attempt to fix ext items dictionary, transaction isolation ch…
Browse files Browse the repository at this point in the history
…anged to repeatable_read for h2 and postgresql
  • Loading branch information
1azyman committed May 15, 2018
1 parent f332e4c commit da4ee61
Show file tree
Hide file tree
Showing 12 changed files with 42 additions and 58 deletions.
Expand Up @@ -232,7 +232,7 @@ public void test120AddExtensionProperty() throws Exception {
repositoryService.modifyObject(UserType.class, userOid, delta.getModifications(), result);

if (baseHelper.getConfiguration().isUsingH2()) {
AssertJUnit.assertEquals(7, queryCountInterceptor.getQueryCount());
AssertJUnit.assertEquals(6, queryCountInterceptor.getQueryCount());
}

Session session = factory.openSession();
Expand Down
Expand Up @@ -152,16 +152,16 @@ public void beforeClass() throws Exception {
}

private void prepareItemDefinitions() {
fooDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<String>(FOO_QNAME, DOMUtil.XSD_STRING, prismContext), null);
shoeSizeDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<Integer>(SHOE_SIZE_QNAME, DOMUtil.XSD_INT, prismContext), null);
a1Definition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<String>(A1_QNAME, DOMUtil.XSD_STRING, prismContext), null);
stringTypeDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Integer>(STRING_TYPE_QNAME, DOMUtil.XSD_STRING, prismContext), null);
intTypeDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Integer>(INT_TYPE_QNAME, DOMUtil.XSD_INT, prismContext), null);
longTypeDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Long>(LONG_TYPE_QNAME, DOMUtil.XSD_LONG, prismContext), null);
weaponDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<Integer>(WEAPON_QNAME, DOMUtil.XSD_STRING, prismContext), null);
fooDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<String>(FOO_QNAME, DOMUtil.XSD_STRING, prismContext), false);
shoeSizeDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<Integer>(SHOE_SIZE_QNAME, DOMUtil.XSD_INT, prismContext), false);
a1Definition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<String>(A1_QNAME, DOMUtil.XSD_STRING, prismContext), false);
stringTypeDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Integer>(STRING_TYPE_QNAME, DOMUtil.XSD_STRING, prismContext));
intTypeDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Integer>(INT_TYPE_QNAME, DOMUtil.XSD_INT, prismContext));
longTypeDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Long>(LONG_TYPE_QNAME, DOMUtil.XSD_LONG, prismContext));
weaponDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<Integer>(WEAPON_QNAME, DOMUtil.XSD_STRING, prismContext), false);
overrideActivationDefinition = extItemDictionary.createOrFindItemDefinition(new PrismPropertyDefinitionImpl<ActivationStatusType>(OVERRIDE_ACTIVATION_QNAME,
ACTIVATION_STATUS_TYPE_QNAME, prismContext), null);
skipAutogenerationDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Boolean>(SKIP_AUTOGENERATION_QNAME, DOMUtil.XSD_BOOLEAN, prismContext), null);
ACTIVATION_STATUS_TYPE_QNAME, prismContext), false);
skipAutogenerationDefinition = extItemDictionary.findItemByDefinition(new PrismPropertyDefinitionImpl<Boolean>(SKIP_AUTOGENERATION_QNAME, DOMUtil.XSD_BOOLEAN, prismContext));
}

@Test
Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.evolveum.midpoint.prism.schema.SchemaRegistry;
import com.evolveum.midpoint.repo.sql.data.common.any.RAnyConverter;
import com.evolveum.midpoint.repo.sql.data.common.any.RAnyValue;
import com.evolveum.midpoint.repo.sql.util.DtoTranslationException;
import com.evolveum.midpoint.schema.DeltaConvertor;
import com.evolveum.midpoint.schema.SchemaConstantsGenerated;
import com.evolveum.midpoint.util.DOMUtil;
Expand Down Expand Up @@ -196,7 +197,15 @@ public void testExtensionEnum() throws Exception {


RAnyConverter converter = new RAnyConverter(prismContext, extItemDictionary);
Set<RAnyValue<?>> values = converter.convertToRValue(item, false, null);
Set<RAnyValue<?>> values;
try {
values = converter.convertToRValue(item, false);
AssertJUnit.fail("Should have throw serialization related exception after creating ext item");
} catch (DtoTranslationException ex) {
AssertJUnit.assertTrue(SerializationRelatedException.class.equals(ex.getCause().getClass()));
}

values = converter.convertToRValue(item, false);

AssertJUnit.assertEquals("Expected only one enum value, but was " + values.size(), 1, values.size());

Expand Down
Expand Up @@ -405,7 +405,7 @@ private static String getDefaultHibernateHbm2ddl(Database database) {

private void computeDefaultConcurrencyParameters() {
if (isUsingH2()) {
defaultTransactionIsolation = TransactionIsolation.SERIALIZABLE;
defaultTransactionIsolation = TransactionIsolation.READ_COMMITTED;
defaultLockForUpdateViaHibernate = false;
defaultLockForUpdateViaSql = false;
defaultUseReadOnlyTransactions = false; // h2 does not support "SET TRANSACTION READ ONLY" command
Expand All @@ -420,7 +420,7 @@ private void computeDefaultConcurrencyParameters() {
defaultLockForUpdateViaSql = true;
defaultUseReadOnlyTransactions = true;
} else if (isUsingPostgreSQL()) {
defaultTransactionIsolation = TransactionIsolation.SERIALIZABLE;
defaultTransactionIsolation = TransactionIsolation.REPEATABLE_READ;
defaultLockForUpdateViaHibernate = false;
defaultLockForUpdateViaSql = false;
defaultUseReadOnlyTransactions = true;
Expand Down
Expand Up @@ -749,7 +749,7 @@ public static void copyFromJAXB(PrismContainerValue<?> containerValue, RObject<?
//TODO: is this enough? should we try items without definitions?
if (items != null) {
for (Item<?,?> item : items) {
Set<RAnyValue<?>> converted = converter.convertToRValue(item, false, null);
Set<RAnyValue<?>> converted = converter.convertToRValue(item, false);
if (generatorResult.isGeneratedOid()) {
converted.stream().forEach(v -> v.setTransient(true));
}
Expand Down
Expand Up @@ -51,9 +51,6 @@
*/
public class RAnyConverter {

// temporary
public static final ThreadLocal<Session> sessionThreadLocal = new ThreadLocal<>();

private enum ValueType {

BOOLEAN(Boolean.class, ROExtBoolean.class, RAExtBoolean.class),
Expand Down Expand Up @@ -134,13 +131,9 @@ private RAnyValue extractAndCreateValue(ItemDefinition def, PrismPropertyValue p
return assignment ? type.createNewAExtValue(extractedValue) : type.createNewOExtValue(extractedValue);
}

public RAnyValue convertToRValue(PrismValue value, boolean assignment, @Nullable Session session) throws SchemaException {
public RAnyValue convertToRValue(PrismValue value, boolean assignment) throws SchemaException {
RAnyValue rValue;

if (session == null) {
session = sessionThreadLocal.get();
}

ItemDefinition definition = value.getParent().getDefinition();

if (!isIndexed(definition, value.getParent().getElementName(), prismContext)) {
Expand All @@ -164,13 +157,13 @@ public RAnyValue convertToRValue(PrismValue value, boolean assignment, @Nullable
throw new AssertionError("Wrong value type: " + value);
}

rValue.setItem(extItemDictionary.createOrFindItemDefinition(definition, session));
rValue.setItem(extItemDictionary.createOrFindItemDefinition(definition));

return rValue;
}

//todo assignment parameter really messed up this method, proper interfaces must be introduced later [lazyman]
public Set<RAnyValue<?>> convertToRValue(Item item, boolean assignment, @Nullable Session session) throws SchemaException, DtoTranslationException {
public Set<RAnyValue<?>> convertToRValue(Item item, boolean assignment) throws SchemaException, DtoTranslationException {
Validate.notNull(item, "Object for converting must not be null.");
Validate.notNull(item.getDefinition(), "Item '" + item.getElementName() + "' without definition can't be saved.");

Expand All @@ -188,7 +181,7 @@ public Set<RAnyValue<?>> convertToRValue(Item item, boolean assignment, @Nullabl
RAnyValue rValue;
List<PrismValue> values = item.getValues();
for (PrismValue value : values) {
rValue = convertToRValue(value, assignment, session);
rValue = convertToRValue(value, assignment);
rValues.add(rValue);
}
} catch (Exception ex) {
Expand Down Expand Up @@ -260,15 +253,6 @@ private static boolean isIndexedByDefault(ItemDefinition definition, PrismContex
}
}

// private RItemKind getItemKind(Itemable itemable) {
// Validate.notNull(itemable, "Value parent must not be null.");
// if (itemable instanceof Item) {
// return RItemKind.getTypeFromItemClass(((Item) itemable).getClass());
// }
//
// return RItemKind.getTypeFromDeltaClass(((ItemDelta) itemable).getClass());
// }

@NotNull
private <T> T extractValue(PrismPropertyValue value, Class<T> returnType) throws SchemaException {
ItemDefinition definition = value.getParent().getDefinition();
Expand Down
Expand Up @@ -298,7 +298,7 @@ private static void copyFromJAXB(PrismContainerValue containerValue, RAssignment
try {
List<Item<?,?>> items = containerValue.getItems();
for (Item item : items) {
values.addAll(converter.convertToRValue(item, true, null));
values.addAll(converter.convertToRValue(item, true));
}
} catch (Exception ex) {
throw new DtoTranslationException(ex.getMessage(), ex);
Expand Down
Expand Up @@ -94,18 +94,23 @@ private void fetchItemsAttempt() {
}

@NotNull
public synchronized RExtItem createOrFindItemDefinition(@NotNull ItemDefinition<?> definition, Session session) {
return createOrFindItemByDefinitionInternal(definition, session, true);
public synchronized RExtItem createOrFindItemDefinition(@NotNull ItemDefinition<?> definition, boolean throwExceptionAfterCreate) {
return createOrFindItemByDefinitionInternal(definition, true, throwExceptionAfterCreate);
}

@NotNull
public synchronized RExtItem createOrFindItemDefinition(@NotNull ItemDefinition<?> definition) {
return createOrFindItemByDefinitionInternal(definition, true, true);
}

@Nullable
public synchronized RExtItem findItemByDefinition(@NotNull ItemDefinition<?> definition, Session session) {
return createOrFindItemByDefinitionInternal(definition, session, false);
public synchronized RExtItem findItemByDefinition(@NotNull ItemDefinition<?> definition) {
return createOrFindItemByDefinitionInternal(definition, false, true);
}

@Contract("_, _, true -> !null")
private synchronized RExtItem createOrFindItemByDefinitionInternal(
@NotNull ItemDefinition<?> definition, Session session, boolean create) {
@NotNull ItemDefinition<?> definition, boolean create, boolean throwExceptionAfterCreate) {

boolean fetchedNow = fetchItemsIfNeeded();
RExtItem.Key key = RExtItem.createKeyFromDefinition(definition);
Expand All @@ -120,31 +125,19 @@ private synchronized RExtItem createOrFindItemByDefinitionInternal(
if (item == null && create) {
LOGGER.debug("Ext item for {} not found even in current items; creating it.", key);

boolean restartSession = shouldRestartParentOperation(session);

if (restartSession) {
session.getTransaction().rollback();
}

item = RExtItem.createFromDefinition(definition);

final RExtItem i = item;
executeAttempts("addExtItem", "Add ext item", () -> addExtItemAttempt(i));

if (restartSession) {
if (throwExceptionAfterCreate) {
throw new SerializationRelatedException("Restarting parent operation");
}
}

return item;
}

private boolean shouldRestartParentOperation(Session session) {
return baseHelper.getConfiguration().isUsingH2()
&& session != null
&& session.isDirty();
}

@PostConstruct
public synchronized void initialize() {
itemsByKey = null;
Expand Down
Expand Up @@ -103,7 +103,6 @@ public Session beginTransaction(boolean readOnly) {
LOGGER.trace("Marking transaction as read only.");
session.doWork(connection -> connection.createStatement().execute("SET TRANSACTION READ ONLY"));
}
RAnyConverter.sessionThreadLocal.set(session); // TODO fix this hack
return session;
}

Expand Down Expand Up @@ -146,7 +145,6 @@ public void cleanupSessionAndResult(Session session, OperationResult result) {
if (result != null && result.isUnknown()) {
result.computeStatus();
}
RAnyConverter.sessionThreadLocal.set(null); // TODO fix this hack
}

public void handleGeneralException(Exception ex, Session session, OperationResult result) {
Expand Down
Expand Up @@ -425,7 +425,7 @@ private void processAnyExtensionDeltaValues(Collection<PrismValue> values,
try {
Collection<PrismEntityPair<RAnyValue>> extValues = new ArrayList<>();
for (PrismValue value : values) {
RAnyValue extValue = converter.convertToRValue(value, object == null, null);
RAnyValue extValue = converter.convertToRValue(value, object == null);
if (extValue == null) {
continue;
}
Expand Down
Expand Up @@ -280,7 +280,7 @@ public <T extends ObjectType> void updateFullObject(RObject object, PrismObject<
object.setFullObject(fullObject);

if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Updating full object xml column finished. Xml:\n", xml);
LOGGER.trace("Updating full object xml column finished. Xml:\n{}", xml);
}
}

Expand Down
Expand Up @@ -149,7 +149,7 @@ private Condition createJoinCondition(String joinedItemAlias, JpaLinkDefinition
conjunction.add(hibernateQuery.createEq(joinedItemAlias + ".ownerType", anyLinkDef.getOwnerType()));
}
ExtItemDictionary dictionary = context.getExtItemDictionary();
RExtItem extItemDefinition = dictionary.findItemByDefinition(anyLinkDef.getItemDefinition(), context.getSession());
RExtItem extItemDefinition = dictionary.findItemByDefinition(anyLinkDef.getItemDefinition());
if (extItemDefinition != null) {
conjunction.add(hibernateQuery.createEq(joinedItemAlias + "." + RAnyValue.F_ITEM + "." + RExtItem.F_ID,
extItemDefinition.getId()));
Expand Down

0 comments on commit da4ee61

Please sign in to comment.