1 19 20 package org.apache.cayenne.access; 21 22 import java.util.Collection ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import org.apache.cayenne.CayenneRuntimeException; 28 import org.apache.cayenne.ObjectId; 29 import org.apache.cayenne.Persistent; 30 import org.apache.cayenne.dba.PkGenerator; 31 import org.apache.cayenne.map.DbAttribute; 32 import org.apache.cayenne.map.DbEntity; 33 import org.apache.cayenne.map.DbJoin; 34 import org.apache.cayenne.map.DbRelationship; 35 import org.apache.cayenne.map.EntitySorter; 36 import org.apache.cayenne.map.ObjAttribute; 37 import org.apache.cayenne.map.ObjEntity; 38 import org.apache.cayenne.query.InsertBatchQuery; 39 import org.apache.cayenne.reflect.ClassDescriptor; 40 41 45 class DataDomainInsertBucket extends DataDomainSyncBucket { 46 47 DataDomainInsertBucket(DataDomainFlushAction parent) { 48 super(parent); 49 } 50 51 void appendQueriesInternal(Collection queries) { 52 53 DataDomainDBDiffBuilder diffBuilder = new DataDomainDBDiffBuilder(); 54 55 EntitySorter sorter = parent.getDomain().getEntitySorter(); 56 sorter.sortDbEntities(dbEntities, false); 57 58 Iterator i = dbEntities.iterator(); 59 while (i.hasNext()) { 60 DbEntity dbEntity = (DbEntity) i.next(); 61 List objEntitiesForDbEntity = (List ) descriptorsByDbEntity.get(dbEntity); 62 63 InsertBatchQuery batch = new InsertBatchQuery(dbEntity, 27); 64 65 Iterator j = objEntitiesForDbEntity.iterator(); 66 while (j.hasNext()) { 67 ClassDescriptor descriptor = (ClassDescriptor) j.next(); 68 69 diffBuilder.reset(descriptor.getEntity(), dbEntity); 70 71 boolean isMasterDbEntity = (descriptor.getEntity().getDbEntity() == dbEntity); 72 73 List objects = (List ) (isMasterDbEntity ? objectsByDescriptor 76 .get(descriptor) : objectsByDescriptor.remove(descriptor)); 77 78 if (objects.isEmpty()) { 79 continue; 80 } 81 82 checkReadOnly(descriptor.getEntity()); 83 84 if (isMasterDbEntity) { 85 createPermIdsForObjEntity(descriptor, objects); 86 sorter.sortObjectsForEntity(descriptor.getEntity(), objects, false); 87 } 88 89 for (Iterator k = objects.iterator(); k.hasNext();) { 90 Persistent o = (Persistent) k.next(); 91 92 Map snapshot = diffBuilder.buildDBDiff(parent.objectDiff(o 93 .getObjectId())); 94 95 batch.add(snapshot, o.getObjectId()); 96 } 97 } 98 99 queries.add(batch); 100 } 101 } 102 103 void createPermIdsForObjEntity(ClassDescriptor descriptor, List dataObjects) { 104 105 if (dataObjects.isEmpty()) { 106 return; 107 } 108 109 ObjEntity objEntity = descriptor.getEntity(); 110 DbEntity dbEntity = objEntity.getDbEntity(); 111 DataNode node = parent.getDomain().lookupDataNode(dbEntity.getDataMap()); 112 boolean supportsGeneratedKeys = node.getAdapter().supportsGeneratedKeys(); 113 114 PkGenerator pkGenerator = node.getAdapter().getPkGenerator(); 115 116 Iterator i = dataObjects.iterator(); 117 while (i.hasNext()) { 118 119 Persistent object = (Persistent) i.next(); 120 ObjectId id = object.getObjectId(); 121 if (id == null || !id.isTemporary()) { 122 continue; 123 } 124 125 Map idMap = id.getReplacementIdMap(); 127 128 boolean autoPkDone = false; 129 Iterator it = dbEntity.getPrimaryKey().iterator(); 130 while (it.hasNext()) { 131 DbAttribute dbAttr = (DbAttribute) it.next(); 132 String dbAttrName = dbAttr.getName(); 133 134 if (idMap.containsKey(dbAttrName)) { 135 continue; 136 } 137 138 ObjAttribute objAttr = objEntity.getAttributeForDbAttribute(dbAttr); 140 if (objAttr != null) { 141 142 Object value = descriptor 143 .getProperty(objAttr.getName()) 144 .readPropertyDirectly(object); 145 146 if (value != null) { 147 if (!(value instanceof Number && ((Number ) value).intValue() == 0)) { 149 idMap.put(dbAttrName, value); 150 continue; 151 } 152 } 153 } 154 155 if (supportsGeneratedKeys && dbAttr.isGenerated()) { 157 continue; 158 } 159 160 if (isPropagated(dbAttr)) { 162 continue; 163 } 164 165 if (autoPkDone) { 168 throw new CayenneRuntimeException( 169 "Primary Key autogeneration only works for a single attribute."); 170 } 171 172 try { 174 Object pkValue = pkGenerator.generatePkForDbEntity(node, dbEntity); 175 idMap.put(dbAttrName, pkValue); 176 autoPkDone = true; 177 } 178 catch (Exception ex) { 179 throw new CayenneRuntimeException("Error generating PK: " 180 + ex.getMessage(), ex); 181 } 182 } 183 } 184 } 185 186 boolean isPropagated(DbAttribute attribute) { 188 Iterator it = attribute.getEntity().getRelationships().iterator(); 189 while (it.hasNext()) { 190 191 DbRelationship dbRel = (DbRelationship) it.next(); 192 if (!dbRel.isToMasterPK()) { 193 continue; 194 } 195 196 Iterator joins = dbRel.getJoins().iterator(); 197 while (joins.hasNext()) { 198 DbJoin join = (DbJoin) joins.next(); 199 if (attribute.getName().equals(join.getSourceName())) { 200 return true; 201 } 202 } 203 } 204 205 return false; 206 } 207 } 208 | Popular Tags |