use of org.datanucleus.ExecutionContext in project datanucleus-rdbms by datanucleus.
the class AbstractArrayStore method set.
/**
* Method to set the array for the specified owner to the passed value.
* @param op ObjectProvider for the owner
* @param array the array
* @return Whether the array was updated successfully
*/
public boolean set(ObjectProvider op, Object array) {
if (array == null || Array.getLength(array) == 0) {
return true;
}
// Validate all elements for writing
ExecutionContext ec = op.getExecutionContext();
int length = Array.getLength(array);
for (int i = 0; i < length; i++) {
Object obj = Array.get(array, i);
validateElementForWriting(ec, obj, null);
}
boolean modified = false;
List exceptions = new ArrayList();
boolean batched = allowsBatching() && length > 1;
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
try {
processBatchedWrites(mconn);
// Loop through all elements to be added
E element = null;
for (int i = 0; i < length; i++) {
element = (E) Array.get(array, i);
try {
// Add the row to the join table
int[] rc = internalAdd(op, element, mconn, batched, i, (i == length - 1));
if (rc != null) {
for (int j = 0; j < rc.length; j++) {
if (rc[j] > 0) {
// At least one record was inserted
modified = true;
}
}
}
} catch (MappedDatastoreException mde) {
exceptions.add(mde);
NucleusLogger.DATASTORE.error("Exception thrown in set of element", mde);
}
}
} finally {
mconn.release();
}
} catch (MappedDatastoreException e) {
exceptions.add(e);
NucleusLogger.DATASTORE.error("Exception thrown in set of element", e);
}
if (!exceptions.isEmpty()) {
// Throw all exceptions received as the cause of a NucleusDataStoreException so the user can see which
// record(s) didn't persist
String msg = Localiser.msg("056009", ((Exception) exceptions.get(0)).getMessage());
NucleusLogger.DATASTORE.error(msg);
throw new NucleusDataStoreException(msg, (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]), op.getObject());
}
return modified;
}
use of org.datanucleus.ExecutionContext in project datanucleus-rdbms by datanucleus.
the class AbstractArrayStore method add.
/**
* Adds one element to the association owner vs elements
* @param op ObjectProvider for the container
* @param element The element to add
* @param position The position to add this element at
* @return Whether it was successful
*/
public boolean add(ObjectProvider op, E element, int position) {
ExecutionContext ec = op.getExecutionContext();
validateElementForWriting(ec, element, null);
boolean modified = false;
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
try {
// Add a row to the join table
int[] returnCode = internalAdd(op, element, mconn, false, position, true);
if (returnCode[0] > 0) {
modified = true;
}
} finally {
mconn.release();
}
} catch (MappedDatastoreException e) {
throw new NucleusDataStoreException(Localiser.msg("056009", e.getMessage()), e.getCause());
}
return modified;
}
use of org.datanucleus.ExecutionContext in project datanucleus-rdbms by datanucleus.
the class LocateRequest method execute.
/**
* Method performing the retrieval of the record from the datastore.
* Takes the constructed retrieval query and populates with the specific record information.
* @param op ObjectProvider for the record to be retrieved
*/
public void execute(ObjectProvider op) {
if (statementLocked != null) {
ExecutionContext ec = op.getExecutionContext();
RDBMSStoreManager storeMgr = table.getStoreManager();
boolean locked = ec.getSerializeReadForClass(op.getClassMetaData().getFullClassName());
LockMode lockType = ec.getLockManager().getLockMode(op.getInternalObjectId());
if (lockType != LockMode.LOCK_NONE) {
if (lockType == LockMode.LOCK_PESSIMISTIC_READ || lockType == LockMode.LOCK_PESSIMISTIC_WRITE) {
// Override with pessimistic lock
locked = true;
}
}
String statement = (locked ? statementLocked : statementUnlocked);
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
PreparedStatement ps = sqlControl.getStatementForQuery(mconn, statement);
AbstractClassMetaData cmd = op.getClassMetaData();
try {
// Provide the primary key field(s)
if (cmd.getIdentityType() == IdentityType.DATASTORE) {
StatementMappingIndex datastoreIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.DATASTORE_ID.getFieldNumber());
for (int i = 0; i < datastoreIdx.getNumberOfParameterOccurrences(); i++) {
table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, datastoreIdx.getParameterPositionsForOccurrence(i), op.getInternalObjectId());
}
} else if (cmd.getIdentityType() == IdentityType.APPLICATION) {
op.provideFields(cmd.getPKMemberPositions(), new ParameterSetter(op, ps, mappingDefinition));
}
JavaTypeMapping multitenancyMapping = table.getSurrogateMapping(SurrogateColumnType.MULTITENANCY, false);
if (multitenancyMapping != null) {
// Set MultiTenancy parameter in statement
StatementMappingIndex multitenancyIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.MULTITENANCY.getFieldNumber());
String tenantId = ec.getNucleusContext().getMultiTenancyId(ec, cmd);
for (int i = 0; i < multitenancyIdx.getNumberOfParameterOccurrences(); i++) {
multitenancyMapping.setObject(ec, ps, multitenancyIdx.getParameterPositionsForOccurrence(i), tenantId);
}
}
JavaTypeMapping softDeleteMapping = table.getSurrogateMapping(SurrogateColumnType.SOFTDELETE, false);
if (softDeleteMapping != null) {
// Set SoftDelete parameter in statement
StatementMappingIndex softDeleteIdx = mappingDefinition.getMappingForMemberPosition(SurrogateColumnType.SOFTDELETE.getFieldNumber());
for (int i = 0; i < softDeleteIdx.getNumberOfParameterOccurrences(); i++) {
softDeleteMapping.setObject(ec, ps, softDeleteIdx.getParameterPositionsForOccurrence(i), Boolean.FALSE);
}
}
// Execute the statement
ResultSet rs = sqlControl.executeStatementQuery(ec, mconn, statement, ps);
try {
if (!rs.next()) {
NucleusLogger.DATASTORE_RETRIEVE.info(Localiser.msg("050018", op.getInternalObjectId()));
throw new NucleusObjectNotFoundException("No such database row", op.getInternalObjectId());
}
} finally {
rs.close();
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException sqle) {
String msg = Localiser.msg("052220", op.getObjectAsPrintable(), statement, sqle.getMessage());
NucleusLogger.DATASTORE_RETRIEVE.warn(msg);
List exceptions = new ArrayList();
exceptions.add(sqle);
while ((sqle = sqle.getNextException()) != null) {
exceptions.add(sqle);
}
throw new NucleusDataStoreException(msg, (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]));
}
}
}
use of org.datanucleus.ExecutionContext in project datanucleus-rdbms by datanucleus.
the class UpdateRequest method execute.
/**
* Method performing the update of the record in the datastore.
* Takes the constructed update query and populates with the specific record information.
* @param op The ObjectProvider for the record to be updated
*/
public void execute(ObjectProvider op) {
// Choose the statement based on whether optimistic or not
String stmt = null;
ExecutionContext ec = op.getExecutionContext();
boolean optimisticChecks = (versionMetaData != null && ec.getTransaction().getOptimistic() && versionChecks);
stmt = optimisticChecks ? updateStmtOptimistic : updateStmt;
if (stmt != null) {
// TODO Support surrogate update user/timestamp
AbstractMemberMetaData[] mmds = cmd.getManagedMembers();
for (int i = 0; i < mmds.length; i++) {
if (// TODO Make this accessible from cmd
mmds[i].isUpdateTimestamp()) {
op.replaceField(mmds[i].getAbsoluteFieldNumber(), new Timestamp(ec.getTransaction().getIsActive() ? ec.getTransaction().getBeginTime() : System.currentTimeMillis()));
} else if (// TODO Make this accessible from cmd
mmds[i].isUpdateUser()) {
op.replaceField(mmds[i].getAbsoluteFieldNumber(), ec.getNucleusContext().getCurrentUser(ec));
}
}
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
// Debug info about fields being updated
StringBuilder fieldStr = new StringBuilder();
if (updateFieldNumbers != null) {
for (int i = 0; i < updateFieldNumbers.length; i++) {
if (fieldStr.length() > 0) {
fieldStr.append(",");
}
fieldStr.append(cmd.getMetaDataForManagedMemberAtAbsolutePosition(updateFieldNumbers[i]).getName());
}
}
if (versionMetaData != null && versionMetaData.getFieldName() == null) {
if (fieldStr.length() > 0) {
fieldStr.append(",");
}
fieldStr.append("[VERSION]");
}
// Debug information about what we are updating
NucleusLogger.PERSISTENCE.debug(Localiser.msg("052214", op.getObjectAsPrintable(), fieldStr.toString(), table));
}
RDBMSStoreManager storeMgr = table.getStoreManager();
boolean batch = false;
// TODO Set the batch flag based on whether we have no other SQL being invoked in here just our UPDATE
try {
ManagedConnection mconn = storeMgr.getConnectionManager().getConnection(ec);
SQLController sqlControl = storeMgr.getSQLController();
try {
// Perform the update
PreparedStatement ps = sqlControl.getStatementForUpdate(mconn, stmt, batch);
try {
Object currentVersion = op.getTransactionalVersion();
Object nextVersion = null;
if (// TODO What if strategy is NONE?
versionMetaData != null) {
// Set the next version in the object
if (versionMetaData.getFieldName() != null) {
// Version field
AbstractMemberMetaData verfmd = cmd.getMetaDataForMember(table.getVersionMetaData().getFieldName());
if (currentVersion instanceof Number) {
// Cater for Integer-based versions
currentVersion = Long.valueOf(((Number) currentVersion).longValue());
}
nextVersion = ec.getLockManager().getNextVersion(versionMetaData, currentVersion);
if (verfmd.getType() == Integer.class || verfmd.getType() == int.class) {
// Cater for Integer-based versions
nextVersion = Integer.valueOf(((Number) nextVersion).intValue());
}
op.replaceField(verfmd.getAbsoluteFieldNumber(), nextVersion);
} else {
// Surrogate version column
nextVersion = ec.getLockManager().getNextVersion(versionMetaData, currentVersion);
}
op.setTransactionalVersion(nextVersion);
}
// SELECT clause - set the required fields to be updated
if (updateFieldNumbers != null) {
StatementClassMapping mappingDefinition = new StatementClassMapping();
StatementMappingIndex[] idxs = stmtMappingDefinition.getUpdateFields();
for (int i = 0; i < idxs.length; i++) {
if (idxs[i] != null) {
mappingDefinition.addMappingForMember(i, idxs[i]);
}
}
op.provideFields(updateFieldNumbers, new ParameterSetter(op, ps, mappingDefinition));
}
if (versionMetaData != null && versionMetaData.getFieldName() == null) {
// SELECT clause - set the surrogate version column to the new version
StatementMappingIndex mapIdx = stmtMappingDefinition.getUpdateVersion();
for (int i = 0; i < mapIdx.getNumberOfParameterOccurrences(); i++) {
table.getSurrogateMapping(SurrogateColumnType.VERSION, false).setObject(ec, ps, mapIdx.getParameterPositionsForOccurrence(i), nextVersion);
}
}
// WHERE clause - primary key fields
if (table.getIdentityType() == IdentityType.DATASTORE) {
// a). datastore identity
StatementMappingIndex mapIdx = stmtMappingDefinition.getWhereDatastoreId();
for (int i = 0; i < mapIdx.getNumberOfParameterOccurrences(); i++) {
table.getSurrogateMapping(SurrogateColumnType.DATASTORE_ID, false).setObject(ec, ps, mapIdx.getParameterPositionsForOccurrence(i), op.getInternalObjectId());
}
} else {
// b). application/nondurable identity
StatementClassMapping mappingDefinition = new StatementClassMapping();
StatementMappingIndex[] idxs = stmtMappingDefinition.getWhereFields();
for (int i = 0; i < idxs.length; i++) {
if (idxs[i] != null) {
mappingDefinition.addMappingForMember(i, idxs[i]);
}
}
FieldManager fm = null;
if (cmd.getIdentityType() == IdentityType.NONDURABLE) {
fm = new OldValueParameterSetter(op, ps, mappingDefinition);
} else {
fm = new ParameterSetter(op, ps, mappingDefinition);
}
op.provideFields(whereFieldNumbers, fm);
}
if (optimisticChecks) {
if (currentVersion == null) {
// Somehow the version is not set on this object (not read in ?) so report the bug
String msg = Localiser.msg("052201", op.getInternalObjectId(), table);
NucleusLogger.PERSISTENCE.error(msg);
throw new NucleusException(msg);
}
// WHERE clause - current version discriminator
StatementMappingIndex mapIdx = stmtMappingDefinition.getWhereVersion();
for (int i = 0; i < mapIdx.getNumberOfParameterOccurrences(); i++) {
mapIdx.getMapping().setObject(ec, ps, mapIdx.getParameterPositionsForOccurrence(i), currentVersion);
}
}
int[] rcs = sqlControl.executeStatementUpdate(ec, mconn, stmt, ps, !batch);
if (rcs[0] == 0 && optimisticChecks) {
// TODO Batching : when we use batching here we need to process these somehow
throw new NucleusOptimisticException(Localiser.msg("052203", op.getObjectAsPrintable(), op.getInternalObjectId(), "" + currentVersion), op.getObject());
}
} finally {
sqlControl.closeStatement(mconn, ps);
}
} finally {
mconn.release();
}
} catch (SQLException e) {
String msg = Localiser.msg("052215", op.getObjectAsPrintable(), stmt, StringUtils.getStringFromStackTrace(e));
NucleusLogger.DATASTORE_PERSIST.error(msg);
List exceptions = new ArrayList();
exceptions.add(e);
while ((e = e.getNextException()) != null) {
exceptions.add(e);
}
throw new NucleusDataStoreException(msg, (Throwable[]) exceptions.toArray(new Throwable[exceptions.size()]));
}
}
// Execute any mapping actions now that we have done the update
for (int i = 0; i < callbacks.length; ++i) {
try {
if (NucleusLogger.PERSISTENCE.isDebugEnabled()) {
NucleusLogger.PERSISTENCE.debug(Localiser.msg("052216", op.getObjectAsPrintable(), ((JavaTypeMapping) callbacks[i]).getMemberMetaData().getFullFieldName()));
}
callbacks[i].postUpdate(op);
} catch (NotYetFlushedException e) {
op.updateFieldAfterInsert(e.getPersistable(), ((JavaTypeMapping) callbacks[i]).getMemberMetaData().getAbsoluteFieldNumber());
}
}
}
use of org.datanucleus.ExecutionContext in project datanucleus-rdbms by datanucleus.
the class ExpressionUtils method getEqualityExpressionForObjectExpressions.
/**
* Method to generate an equality/inequality expression between two ObjectExpressions.
* Either or both of the expressions can be ObjectLiterals.
* @param expr1 First expression
* @param expr2 Second expression
* @param equals Whether it is equality (otherwise inequality)
* @return The expression
*/
public static BooleanExpression getEqualityExpressionForObjectExpressions(ObjectExpression expr1, ObjectExpression expr2, boolean equals) {
SQLStatement stmt = expr1.stmt;
RDBMSStoreManager storeMgr = stmt.getRDBMSManager();
SQLExpressionFactory exprFactory = storeMgr.getSQLExpressionFactory();
ClassLoaderResolver clr = stmt.getClassLoaderResolver();
ApiAdapter api = storeMgr.getApiAdapter();
if (expr1 instanceof ObjectLiteral && expr2 instanceof ObjectLiteral) {
// ObjectLiterall == ObjectLiteral
ObjectLiteral lit1 = (ObjectLiteral) expr1;
ObjectLiteral lit2 = (ObjectLiteral) expr2;
return new BooleanLiteral(stmt, expr1.mapping, equals ? lit1.getValue().equals(lit2.getValue()) : !lit1.getValue().equals(lit2.getValue()));
} else if (expr1 instanceof ObjectLiteral || expr2 instanceof ObjectLiteral) {
// ObjectExpression == ObjectLiteral, ObjectLiteral == ObjectExpression
BooleanExpression bExpr = null;
boolean secondIsLiteral = (expr2 instanceof ObjectLiteral);
Object value = (!secondIsLiteral ? ((ObjectLiteral) expr1).getValue() : ((ObjectLiteral) expr2).getValue());
if (IdentityUtils.isDatastoreIdentity(value)) {
// Object is an OID
Object valueKey = IdentityUtils.getTargetKeyForDatastoreIdentity(value);
JavaTypeMapping m = storeMgr.getSQLExpressionFactory().getMappingForType(valueKey.getClass(), false);
SQLExpression oidLit = exprFactory.newLiteral(stmt, m, valueKey);
if (equals) {
return (secondIsLiteral ? expr1.subExprs.getExpression(0).eq(oidLit) : expr2.subExprs.getExpression(0).eq(oidLit));
}
return (secondIsLiteral ? expr1.subExprs.getExpression(0).ne(oidLit) : expr2.subExprs.getExpression(0).ne(oidLit));
} else if (IdentityUtils.isSingleFieldIdentity(value)) {
// Object is SingleFieldIdentity
Object valueKey = IdentityUtils.getTargetKeyForSingleFieldIdentity(value);
// This used to use ((SingleFieldId)value).getTargetClass() for some reason, which contradicts the above datastore id method
JavaTypeMapping m = storeMgr.getSQLExpressionFactory().getMappingForType(valueKey.getClass(), false);
SQLExpression oidLit = exprFactory.newLiteral(stmt, m, valueKey);
if (equals) {
return (secondIsLiteral ? expr1.subExprs.getExpression(0).eq(oidLit) : expr2.subExprs.getExpression(0).eq(oidLit));
}
return (secondIsLiteral ? expr1.subExprs.getExpression(0).ne(oidLit) : expr2.subExprs.getExpression(0).ne(oidLit));
} else {
AbstractClassMetaData cmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(value.getClass(), clr);
if (cmd != null) {
// Value is a persistable object
if (cmd.getIdentityType() == IdentityType.APPLICATION) {
// Application identity
if (api.getIdForObject(value) != null) {
// Persistent PC object (FCO)
// Cater for composite PKs and parts of PK being PC mappings, and recursion
ObjectExpression expr = (secondIsLiteral ? expr1 : expr2);
JavaTypeMapping[] pkMappingsApp = new JavaTypeMapping[expr.subExprs.size()];
Object[] pkFieldValues = new Object[expr.subExprs.size()];
int position = 0;
ExecutionContext ec = api.getExecutionContext(value);
JavaTypeMapping thisMapping = expr.mapping;
if (expr.mapping instanceof ReferenceMapping) {
// "InterfaceField == value", so pick an implementation mapping that is castable
thisMapping = null;
ReferenceMapping refMapping = (ReferenceMapping) expr.mapping;
JavaTypeMapping[] implMappings = refMapping.getJavaTypeMapping();
for (int i = 0; i < implMappings.length; i++) {
Class implType = clr.classForName(implMappings[i].getType());
if (implType.isAssignableFrom(value.getClass())) {
thisMapping = implMappings[i];
break;
}
}
}
if (thisMapping == null) {
// Just return a (1=0) since no implementation castable
return exprFactory.newLiteral(stmt, expr1.mapping, false).eq(exprFactory.newLiteral(stmt, expr1.mapping, true));
}
for (int i = 0; i < cmd.getNoOfPrimaryKeyMembers(); i++) {
AbstractMemberMetaData mmd = cmd.getMetaDataForManagedMemberAtAbsolutePosition(cmd.getPKMemberPositions()[i]);
Object fieldValue = ExpressionUtils.getValueForMemberOfObject(ec, mmd, value);
JavaTypeMapping mapping = ((PersistableMapping) thisMapping).getJavaTypeMapping()[i];
if (mapping instanceof PersistableMapping) {
position = ExpressionUtils.populatePrimaryKeyMappingsValuesForPCMapping(pkMappingsApp, pkFieldValues, position, (PersistableMapping) mapping, cmd, mmd, fieldValue, storeMgr, clr);
} else {
pkMappingsApp[position] = mapping;
pkFieldValues[position] = fieldValue;
position++;
}
}
for (int i = 0; i < expr.subExprs.size(); i++) {
SQLExpression source = expr.subExprs.getExpression(i);
SQLExpression target = exprFactory.newLiteral(stmt, pkMappingsApp[i], pkFieldValues[i]);
BooleanExpression subExpr = (secondIsLiteral ? source.eq(target) : target.eq(source));
if (bExpr == null) {
bExpr = subExpr;
} else {
bExpr = bExpr.and(subExpr);
}
}
} else {
// PC object with no id (embedded, or transient maybe)
if (secondIsLiteral) {
for (int i = 0; i < expr1.subExprs.size(); i++) {
// Query should return nothing (so just do "(1 = 0)")
NucleusLogger.QUERY.warn(Localiser.msg("037003", value));
bExpr = exprFactory.newLiteral(stmt, expr1.mapping, false).eq(exprFactory.newLiteral(stmt, expr1.mapping, true));
// It is arguable that we should compare the id with null (as below)
/*bExpr = expr.eq(new NullLiteral(qs));*/
}
} else {
for (int i = 0; i < expr2.subExprs.size(); i++) {
// Query should return nothing (so just do "(1 = 0)")
NucleusLogger.QUERY.warn(Localiser.msg("037003", value));
bExpr = exprFactory.newLiteral(stmt, expr2.mapping, false).eq(exprFactory.newLiteral(stmt, expr2.mapping, true));
// It is arguable that we should compare the id with null (as below)
/*bExpr = expr.eq(new NullLiteral(qs));*/
}
}
}
// TODO Allow for !equals
return bExpr;
} else if (cmd.getIdentityType() == IdentityType.DATASTORE) {
// Datastore identity
SQLExpression source = (secondIsLiteral ? expr1.subExprs.getExpression(0) : expr2.subExprs.getExpression(0));
JavaTypeMapping mapping = (secondIsLiteral ? expr1.mapping : expr2.mapping);
Object objectId = api.getIdForObject(value);
if (objectId == null) {
// PC object with no id (embedded, or transient maybe)
// Query should return nothing (so just do "(1 = 0)")
NucleusLogger.QUERY.warn(Localiser.msg("037003", value));
// TODO Allow for !equals
return exprFactory.newLiteral(stmt, mapping, false).eq(exprFactory.newLiteral(stmt, mapping, true));
// It is arguable that we should compare the id with null (as below)
/*bExpr = expr.eq(new NullLiteral(qs));*/
}
Object objectIdKey = IdentityUtils.getTargetKeyForDatastoreIdentity(objectId);
JavaTypeMapping m = storeMgr.getSQLExpressionFactory().getMappingForType(objectIdKey.getClass(), false);
SQLExpression oidExpr = exprFactory.newLiteral(stmt, m, objectIdKey);
if (equals) {
return source.eq(oidExpr);
}
return source.ne(oidExpr);
}
} else {
// No metadata, so we either have an application identity, or any object
String pcClassName = storeMgr.getClassNameForObjectID(value, clr, null);
if (pcClassName != null) {
// Object is an application identity
cmd = storeMgr.getNucleusContext().getMetaDataManager().getMetaDataForClass(pcClassName, clr);
return (secondIsLiteral ? ExpressionUtils.getAppIdEqualityExpression(value, expr1, storeMgr, clr, cmd, null, null) : ExpressionUtils.getAppIdEqualityExpression(value, expr2, storeMgr, clr, cmd, null, null));
// TODO Allow for !equals
}
// Value not persistable nor an identity, so return nothing "(1 = 0)"
return exprFactory.newLiteral(stmt, expr1.mapping, false).eq(exprFactory.newLiteral(stmt, expr1.mapping, true));
// TODO Allow for !equals
}
}
} else {
// ObjectExpression == ObjectExpression
BooleanExpression resultExpr = null;
for (int i = 0; i < expr1.subExprs.size(); i++) {
SQLExpression sourceExpr = expr1.subExprs.getExpression(i);
SQLExpression targetExpr = expr2.subExprs.getExpression(i);
if (resultExpr == null) {
resultExpr = sourceExpr.eq(targetExpr);
} else {
resultExpr = resultExpr.and(sourceExpr.eq(targetExpr));
}
}
if (!equals) {
resultExpr = new BooleanExpression(Expression.OP_NOT, resultExpr != null ? resultExpr.encloseInParentheses() : null);
}
return resultExpr;
}
return null;
}
Aggregations