1 56 package org.objectstyle.cayenne.access; 57 58 import java.util.Collections ; 59 import java.util.HashMap ; 60 import java.util.Iterator ; 61 import java.util.List ; 62 import java.util.Map ; 63 64 import org.objectstyle.cayenne.CayenneRuntimeException; 65 import org.objectstyle.cayenne.DataObject; 66 import org.objectstyle.cayenne.dba.PkGenerator; 67 import org.objectstyle.cayenne.exp.Expression; 68 import org.objectstyle.cayenne.exp.ExpressionFactory; 69 import org.objectstyle.cayenne.map.DbAttribute; 70 import org.objectstyle.cayenne.map.DbEntity; 71 import org.objectstyle.cayenne.map.DbJoin; 72 import org.objectstyle.cayenne.map.DbRelationship; 73 import org.objectstyle.cayenne.map.ObjRelationship; 74 import org.objectstyle.cayenne.query.SelectQuery; 75 76 82 final class FlattenedRelationshipUpdate extends RelationshipUpdate { 83 84 FlattenedRelationshipUpdate(DataObject source, DataObject destination, 85 ObjRelationship relationship) { 86 87 super(source, destination, relationship); 88 } 89 90 93 DbEntity getJoinEntity() { 94 List relList = relationship.getDbRelationships(); 95 if (relList.size() != 2) { 96 throw new CayenneRuntimeException( 97 "Only single-step flattened relationships are supported in this operation: " 98 + relationship); 99 } 100 101 DbRelationship firstDbRel = (DbRelationship) relList.get(0); 102 return (DbEntity) firstDbRel.getTargetEntity(); 103 } 104 105 108 Map buildJoinSnapshot() { 109 110 List relList = relationship.getDbRelationships(); 111 if (relList.size() != 2) { 112 throw new CayenneRuntimeException( 113 "Only single-step flattened relationships are supported in this operation: " 114 + relationship); 115 } 116 117 DbRelationship firstDbRel = (DbRelationship) relList.get(0); 118 DbRelationship secondDbRel = (DbRelationship) relList.get(1); 119 120 Map sourceId = source.getObjectId().getIdSnapshot(); 121 Map destinationId = destination.getObjectId().getIdSnapshot(); 122 123 Map snapshot = new HashMap (sourceId.size() + destinationId.size(), 1); 124 List joins = firstDbRel.getJoins(); 125 for (int i = 0, numJoins = joins.size(); i < numJoins; i++) { 126 DbJoin join = (DbJoin) joins.get(i); 127 snapshot.put(join.getTargetName(), sourceId.get(join.getSourceName())); 128 } 129 130 joins = secondDbRel.getJoins(); 131 for (int i = 0, numJoins = joins.size(); i < numJoins; i++) { 132 DbJoin join = (DbJoin) joins.get(i); 133 snapshot.put(join.getSourceName(), destinationId.get(join.getTargetName())); 134 } 135 136 return snapshot; 137 } 138 139 144 Map buildJoinSnapshotForInsert() { 145 Map snapshot = buildJoinSnapshot(); 146 147 boolean autoPkDone = false; 148 DbEntity joinEntity = getJoinEntity(); 149 List pkAttributes = joinEntity.getPrimaryKey(); 150 Iterator it = pkAttributes.iterator(); 151 152 while (it.hasNext()) { 153 DbAttribute dbAttr = (DbAttribute) it.next(); 154 String dbAttrName = dbAttr.getName(); 155 if (snapshot.containsKey(dbAttrName)) { 156 continue; 157 } 158 159 if (autoPkDone) { 160 throw new CayenneRuntimeException( 161 "Primary Key autogeneration only works for a single attribute."); 162 } 163 164 try { 166 DataNode node = source.getDataContext().lookupDataNode( 167 joinEntity.getDataMap()); 168 PkGenerator pkGenerator = node.getAdapter().getPkGenerator(); 169 Object pkValue = pkGenerator.generatePkForDbEntity(node, joinEntity); 170 snapshot.put(dbAttrName, pkValue); 171 autoPkDone = true; 172 } 173 catch (Exception ex) { 174 throw new CayenneRuntimeException("Error generating PK: " 175 + ex.getMessage(), ex); 176 } 177 } 178 179 return snapshot; 180 } 181 182 187 List buildJoinSnapshotsForDelete() { 188 Map snapshot = buildJoinSnapshot(); 189 190 DbEntity joinEntity = getJoinEntity(); 191 List pkAttributes = joinEntity.getPrimaryKey(); 192 Iterator it = pkAttributes.iterator(); 193 194 boolean fetchKey = false; 195 while (it.hasNext()) { 196 DbAttribute dbAttr = (DbAttribute) it.next(); 197 String dbAttrName = dbAttr.getName(); 198 if (!snapshot.containsKey(dbAttrName)) { 199 fetchKey = true; 200 break; 201 } 202 } 203 204 if (!fetchKey) { 205 return Collections.singletonList(snapshot); 206 } 207 208 212 SelectQuery query = new SelectQuery(joinEntity, ExpressionFactory.matchAllDbExp( 213 snapshot, 214 Expression.EQUAL_TO)); 215 query.setFetchingDataRows(true); 216 217 it = pkAttributes.iterator(); 218 while (it.hasNext()) { 219 DbAttribute dbAttr = (DbAttribute) it.next(); 220 query.addCustomDbAttribute(dbAttr.getName()); 221 } 222 223 return source.getDataContext().performQuery(query); 224 } 225 } | Popular Tags |