          (save!-helper this# ~datastore-entity-name))
        (save! [this# parent#]
          (save!-helper this# ~datastore-entity-name :parent parent#)))))
+
+
+;;; Note that the code relies on the API's implicit transaction tracking, and
+;;; the *current-transaction* value is not used. Making it available just in
+;;; case.
+(defmacro with-transaction [& body]
+  `(binding [*current-transaction* (.beginTransaction (get-datastore-service))]
+     (try
+       (let [body-result# ~@body]
+         (.commit *current-transaction*)
+         body-result#)
+       (catch Throwable err#
+         (do (.rollback *current-transaction*)
+             (throw err#))))))

     ;; neither exists: autogenerate
     (and (nil? key-property-value) (nil? metadata-key-value))
     nil
     ;; key property exists
     (not (nil? key-property-value))
     (if parent
         (KeyFactory/createKey (get-key-object parent) datastore-entity-name key-property-value)
         (KeyFactory/createKey datastore-entity-name key-property-value))
     ;; metadata key exists
     (and (not (nil? metadata-key-value)) (instance? Key metadata-key-value))
     metadata-key-value
     ;; something's wrong
     :else (throw (RuntimeException.
                   "entity has no valid :key metadata, and has no fields marked :key")))))

         :else v)))


(defn get-key-object-helper [entity-record key-property datastore-entity-name &
                             {:keys [parent]}]
  (let [entity-record-metadata (meta entity-record)
