use of org.apache.cayenne.Persistent in project cayenne by apache.
the class QueryAssemblerHelper method appendLiteral.
/**
* Appends SQL code to the query buffer to handle <code>val</code> as a
* parameter to the PreparedStatement being built. Adds <code>val</code>
* into QueryAssembler parameter list.
* <p>
* If <code>val</code> is null, "NULL" is appended to the query.
* </p>
* <p>
* If <code>val</code> is a DataObject, its primary key value is used as a
* parameter. <i>Only objects with a single column primary key can be
* used.</i>
*
* @param val
* object that should be appended as a literal to the query. Must
* be of one of "standard JDBC" types, null or a DataObject.
* @param attr
* DbAttribute that has information on what type of parameter is
* being appended.
*/
protected void appendLiteral(Object val, DbAttribute attr, Expression parentExpression) throws IOException {
if (val == null) {
out.append("NULL");
} else if (val instanceof Persistent) {
// TODO: see cay1796
// This check is unlikely to happen,
// since Expression got ObjectId from Persistent object.
// Left for future research.
ObjectId id = ((Persistent) val).getObjectId();
// check if this id is acceptable to be a parameter
if (id == null) {
throw new CayenneRuntimeException("Can't use TRANSIENT object as a query parameter.");
}
if (id.isTemporary()) {
throw new CayenneRuntimeException("Can't use NEW object as a query parameter.");
}
Map<String, Object> snap = id.getIdSnapshot();
if (snap.size() != 1) {
throw new CayenneRuntimeException("Object must have a single primary key column to serve " + "as a query parameter. This object has %s: %s", snap.size(), snap);
}
// checks have been passed, use id value
appendLiteralDirect(snap.get(snap.keySet().iterator().next()), attr, parentExpression);
} else if (val instanceof ObjectId) {
ObjectId id = (ObjectId) val;
if (id.isTemporary()) {
throw new CayenneRuntimeException("Can't use NEW object as a query parameter.");
}
Map<String, Object> snap = id.getIdSnapshot();
if (snap.size() != 1) {
throw new CayenneRuntimeException("Object must have a single primary key column to serve " + "as a query parameter. This object has %s: %s", snap.size(), snap);
}
// checks have been passed, use id value
appendLiteralDirect(snap.get(snap.keySet().iterator().next()), attr, parentExpression);
} else {
appendLiteralDirect(val, attr, parentExpression);
}
}
use of org.apache.cayenne.Persistent in project cayenne by apache.
the class AshwoodEntitySorter method sortObjectsForEntity.
@Override
public void sortObjectsForEntity(ObjEntity objEntity, List<?> objects, boolean deleteOrder) {
indexSorter();
List<Persistent> persistent = (List<Persistent>) objects;
DbEntity dbEntity = objEntity.getDbEntity();
// if no sorting is required
if (!isReflexive(dbEntity)) {
return;
}
int size = persistent.size();
if (size == 0) {
return;
}
EntityResolver resolver = persistent.get(0).getObjectContext().getEntityResolver();
ClassDescriptor descriptor = resolver.getClassDescriptor(objEntity.getName());
List<DbRelationship> reflexiveRels = reflexiveDbEntities.get(dbEntity);
String[] reflexiveRelNames = new String[reflexiveRels.size()];
for (int i = 0; i < reflexiveRelNames.length; i++) {
DbRelationship dbRel = reflexiveRels.get(i);
ObjRelationship objRel = (dbRel != null ? objEntity.getRelationshipForDbRelationship(dbRel) : null);
reflexiveRelNames[i] = (objRel != null ? objRel.getName() : null);
}
List<Persistent> sorted = new ArrayList<>(size);
Digraph<Persistent, Boolean> objectDependencyGraph = new MapDigraph<>();
Object[] masters = new Object[reflexiveRelNames.length];
for (int i = 0; i < size; i++) {
Persistent current = (Persistent) objects.get(i);
objectDependencyGraph.addVertex(current);
int actualMasterCount = 0;
for (int k = 0; k < reflexiveRelNames.length; k++) {
String reflexiveRelName = reflexiveRelNames[k];
if (reflexiveRelName == null) {
continue;
}
masters[k] = descriptor.getProperty(reflexiveRelName).readProperty(current);
if (masters[k] == null) {
masters[k] = findReflexiveMaster(current, objEntity.getRelationship(reflexiveRelName), current.getObjectId().getEntityName());
}
if (masters[k] != null) {
actualMasterCount++;
}
}
int mastersFound = 0;
for (int j = 0; j < size && mastersFound < actualMasterCount; j++) {
if (i == j) {
continue;
}
Persistent masterCandidate = persistent.get(j);
for (Object master : masters) {
if (masterCandidate == master) {
objectDependencyGraph.putArc(masterCandidate, current, Boolean.TRUE);
mastersFound++;
}
}
}
}
IndegreeTopologicalSort<Persistent> sorter = new IndegreeTopologicalSort<>(objectDependencyGraph);
while (sorter.hasNext()) {
Persistent o = sorter.next();
if (o == null) {
throw new CayenneRuntimeException("Sorting objects for %s failed. Cycles found.", objEntity.getClassName());
}
sorted.add(o);
}
// since API requires sorting within the same array,
// simply replace all objects with objects in the right order...
// may come up with something cleaner later
persistent.clear();
persistent.addAll(sorted);
if (deleteOrder) {
Collections.reverse(persistent);
}
}
use of org.apache.cayenne.Persistent in project cayenne by apache.
the class ValueForNullIT method test.
@Test
public void test() throws Exception {
DbEntity dbEntity = map.getDbEntity("PAINTING");
assertNotNull(dbEntity);
ObjEntity objEntity = map.getObjEntity("Painting");
assertNotNull(objEntity);
// insert some rows before adding "not null" column
final int nrows = 10;
for (int i = 0; i < nrows; i++) {
DataObject o = (DataObject) context.newObject("Painting");
o.writeProperty("paintingTitle", "ptitle" + i);
}
context.commitChanges();
// create and add new column to model and db
DbAttribute column = new DbAttribute("NEWCOL2", Types.VARCHAR, dbEntity);
column.setMandatory(false);
column.setMaxLength(10);
dbEntity.addAttribute(column);
assertTrue(dbEntity.getAttributes().contains(column));
assertEquals(column, dbEntity.getAttribute(column.getName()));
assertTokensAndExecute(1, 0);
// need obj attr to be able to query
ObjAttribute objAttr = new ObjAttribute("newcol2");
objAttr.setDbAttributePath(column.getName());
objEntity.addAttribute(objAttr);
// check that is was merged
assertTokensAndExecute(0, 0);
// set not null
column.setMandatory(true);
// merge to db
assertTokensAndExecute(2, 0);
// check that is was merged
assertTokensAndExecute(0, 0);
// check values for null
Expression qual = ExpressionFactory.matchExp(objAttr.getName(), DEFAULT_VALUE_STRING);
SelectQuery query = new SelectQuery("Painting", qual);
@SuppressWarnings("unchecked") List<Persistent> rows = context.performQuery(query);
assertEquals(nrows, rows.size());
// clean up
dbEntity.removeAttribute(column.getName());
assertTokensAndExecute(1, 0);
assertTokensAndExecute(0, 0);
}
use of org.apache.cayenne.Persistent in project cayenne by apache.
the class ShallowMergeOperation_ClientIT method testMerge_NoOverride.
@Test
public void testMerge_NoOverride() throws Exception {
ObjectContext childContext = runtime.newContext(context);
final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
final ClientMtTable1 modified = context.newObject(ClientMtTable1.class);
context.commitChanges();
final ClientMtTable1 peerModified = (ClientMtTable1) Cayenne.objectForQuery(childContext, new ObjectIdQuery(modified.getObjectId()));
modified.setGlobalAttribute1("M1");
peerModified.setGlobalAttribute1("M2");
assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
assertEquals(PersistenceState.MODIFIED, peerModified.getPersistenceState());
queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
public void execute() {
Persistent peerModified2 = op.merge(modified);
assertSame(peerModified, peerModified2);
assertEquals(PersistenceState.MODIFIED, peerModified2.getPersistenceState());
assertEquals("M2", peerModified.getGlobalAttribute1());
assertEquals("M1", modified.getGlobalAttribute1());
}
});
}
use of org.apache.cayenne.Persistent in project cayenne by apache.
the class ShallowMergeOperation_ClientIT method testMerge_PersistenceStates.
@Test
public void testMerge_PersistenceStates() throws Exception {
createMtTable1DataSet();
final ObjectContext childContext = runtime.newContext(context);
final ShallowMergeOperation op = new ShallowMergeOperation(childContext);
final ClientMtTable1 _new = context.newObject(ClientMtTable1.class);
final ClientMtTable1 hollow = Cayenne.objectForPK(context, ClientMtTable1.class, 33001);
context.invalidateObjects(hollow);
final ClientMtTable1 committed = Cayenne.objectForPK(context, ClientMtTable1.class, 33002);
final ClientMtTable1 modified = Cayenne.objectForPK(context, ClientMtTable1.class, 33003);
modified.setGlobalAttribute1("XXX");
final ClientMtTable1 deleted = Cayenne.objectForPK(context, ClientMtTable1.class, 33004);
context.deleteObjects(deleted);
assertEquals(PersistenceState.HOLLOW, hollow.getPersistenceState());
assertEquals(PersistenceState.COMMITTED, committed.getPersistenceState());
assertEquals(PersistenceState.MODIFIED, modified.getPersistenceState());
assertEquals(PersistenceState.DELETED, deleted.getPersistenceState());
assertEquals(PersistenceState.NEW, _new.getPersistenceState());
queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
public void execute() {
Persistent newPeer = op.merge(_new);
assertEquals(_new.getObjectId(), newPeer.getObjectId());
assertEquals(PersistenceState.COMMITTED, newPeer.getPersistenceState());
assertSame(childContext, newPeer.getObjectContext());
assertSame(context, _new.getObjectContext());
Persistent hollowPeer = op.merge(hollow);
assertEquals(PersistenceState.HOLLOW, hollowPeer.getPersistenceState());
assertEquals(hollow.getObjectId(), hollowPeer.getObjectId());
assertSame(childContext, hollowPeer.getObjectContext());
assertSame(context, hollow.getObjectContext());
Persistent committedPeer = op.merge(committed);
assertEquals(PersistenceState.COMMITTED, committedPeer.getPersistenceState());
assertEquals(committed.getObjectId(), committedPeer.getObjectId());
assertSame(childContext, committedPeer.getObjectContext());
assertSame(context, committed.getObjectContext());
ClientMtTable1 modifiedPeer = op.merge(modified);
assertEquals(PersistenceState.COMMITTED, modifiedPeer.getPersistenceState());
assertEquals(modified.getObjectId(), modifiedPeer.getObjectId());
assertEquals("XXX", modifiedPeer.getGlobalAttribute1());
assertSame(childContext, modifiedPeer.getObjectContext());
assertSame(context, modified.getObjectContext());
Persistent deletedPeer = op.merge(deleted);
assertEquals(PersistenceState.COMMITTED, deletedPeer.getPersistenceState());
assertEquals(deleted.getObjectId(), deletedPeer.getObjectId());
assertSame(childContext, deletedPeer.getObjectContext());
assertSame(context, deleted.getObjectContext());
}
});
}
Aggregations