parse-community / Parse-SDK-Android

The Android SDK for Parse Platform
https://parseplatform.org/
Other
1.89k stars 735 forks source link

android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: ParseObjects.className, ParseObjects.objectId (code 2067) #218

Open alexblack opened 9 years ago

alexblack commented 9 years ago

It looks like after I implemented a retry work around for the failing to save parse installation bug I might have hit a new bug?

My retry code looks like this:

 // Initialize the parse installation
            return parseInit.initParseInstallation().continueWithTask(new Continuation<ParseInstallation, Task<ParseInstallation>>() {
              @Override
              public Task<ParseInstallation> then(Task<ParseInstallation> task) throws Exception {
                if (task.isFaulted()) {
                  // Retry once, try to work around bug that causes '135 deviceType not specified' errors
                  // https://github.com/ParsePlatform/Parse-SDK-Android/issues/203#issuecomment-150045761
                  return parseInit.initParseInstallation().onSuccess(new Continuation<ParseInstallation, ParseInstallation>() {
                    @Override
                    public ParseInstallation then(Task<ParseInstallation> task) throws Exception {
                      App.logEvent(App.this, "parse-installation", "retry-success", task.getResult().getObjectId());
                      return task.getResult();
                    }
                  }, executor);
                } else {
                  return task;
                }
              }
            }, executor);

With initParseInstallation:

  public Task<ParseInstallation> initParseInstallation() {
    final TimingLogger timings = new TimingLogger(TAG, "initParseInstallation");
    Log.d(TAG, "initParseInstallation");
    try {
      final ParseInstallation installation = ParseInstallation.getCurrentInstallation();
      installation.put("flavor", BuildConfig.FLAVOR);
      installation.put("accountId", accountId);
      installation.put("user", ParseUser.getCurrentUser());
      try {
        installation.put("androidId", Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.ANDROID_ID));
        installation.put("android", String.format("%s (%s %s)", Build.VERSION.RELEASE, Build.VERSION.CODENAME, Build.VERSION.INCREMENTAL));
        installation.put("device", String.format("%s (%s)", DeviceUtils.getDeviceName(), Build.HARDWARE));
        installation.put("abi", Build.CPU_ABI);
        installation.put("syncEnabled", Syncer.syncEnabled(ctx));
        installation.increment("appStart");
      } catch (Exception e) {
        App.err(ctx, "Failed to set properties on installation", e);
      }

      if (installation.containsKey("GCMSenderId"))
        installation.remove("GCMSenderId");

      timings.addSplit("setInstall");

      return installation.saveInBackground().continueWithTask(new Continuation<Void, Task<ParseInstallation>>() {
        @Override
        public Task<ParseInstallation> then(Task<Void> task) throws Exception {
          timings.addSplit("onInstall");
          if (task.isFaulted()) {
            if (task.getError() instanceof ParseException) {
              ParseException e = (ParseException) task.getError();
              App.err(ctx, "Failed to save parse installation: " + e.getCode(), new Exception(e));
            } else {
              App.err(ctx, "Failed to save parse installation", new Exception(task.getError()));
            }
            return Task.forError(task.getError());
          } else {
            Log.d(TAG, "Successfully initialized parseInstallation: " + installation.getObjectId());
            return Task.forResult(installation);
          }
        }
      });
    } catch (Exception e) {
      App.err(ctx, "Failed to setup parse installation", e);
      return Task.forError(e);
    }
  }
Non-fatal Exception: java.lang.Exception: android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: ParseObjects.className, ParseObjects.objectId (code 2067)
       at com.aadhk.woinvoice.util.ParseInit$2.then(ProGuard)
       at com.aadhk.woinvoice.util.ParseInit$2.then(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeAfterTask(ProGuard)
       at bolts.Task.access$200(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeAfterTask(ProGuard)
       at bolts.Task.access$200(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
       at java.lang.Thread.run(Thread.java)
Caused by android.database.sqlite.SQLiteConstraintException: UNIQUE constraint failed: ParseObjects.className, ParseObjects.objectId (code 2067)
       at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(SQLiteConnection.java)
       at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java)
       at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java)
       at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java)
       at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java)
       at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java)
       at com.parse.ParseSQLiteDatabase$22.then(ProGuard)
       at com.parse.ParseSQLiteDatabase$22.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task$12.then(ProGuard)
       at bolts.Task$12.then(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
       at java.lang.Thread.run(Thread.java)
alexblack commented 9 years ago

I've also seen another variant with another code:

Non-fatal Exception: java.lang.Exception: android.database.sqlite.SQLiteConstraintException: columns className, objectId are not unique (code 19)
       at com.aadhk.woinvoice.util.ParseInit$2.then(ProGuard)
       at com.aadhk.woinvoice.util.ParseInit$2.then(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeAfterTask(ProGuard)
       at bolts.Task.access$200(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeAfterTask(ProGuard)
       at bolts.Task.access$200(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task$11.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.access$100(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task$10.then(ProGuard)
       at bolts.Task.runContinuations(ProGuard)
       at bolts.Task.access$600(ProGuard)
       at bolts.Task$TaskCompletionSource.trySetError(ProGuard)
       at bolts.Task$TaskCompletionSource.setError(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$15$1.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
       at java.lang.Thread.run(Thread.java)
Caused by android.database.sqlite.SQLiteConstraintException: columns className, objectId are not unique (code 19)
       at android.database.sqlite.SQLiteConnection.nativeExecuteForChangedRowCount(SQLiteConnection.java)
       at android.database.sqlite.SQLiteConnection.executeForChangedRowCount(SQLiteConnection.java)
       at android.database.sqlite.SQLiteSession.executeForChangedRowCount(SQLiteSession.java)
       at android.database.sqlite.SQLiteStatement.executeUpdateDelete(SQLiteStatement.java)
       at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java)
       at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java)
       at com.parse.ParseSQLiteDatabase$22.then(ProGuard)
       at com.parse.ParseSQLiteDatabase$22.then(ProGuard)
       at bolts.Task$14.run(ProGuard)
       at bolts.BoltsExecutors$ImmediateExecutor.execute(ProGuard)
       at bolts.Task.completeImmediately(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task.continueWith(ProGuard)
       at bolts.Task$12.then(ProGuard)
       at bolts.Task$12.then(ProGuard)
       at bolts.Task$15.run(ProGuard)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java)
       at java.lang.Thread.run(Thread.java)
parse-github-bot commented 9 years ago

Thank you for your feedback. We prioritize issues that have clear and concise repro steps. Please see our Bug Reporting Guidelines about what information should be added to this issue.

Please try the latest SDK. Our release notes have details about what issues were fixed in each release.

In addition, you might find the following resources helpful:

wangmengyan95 commented 9 years ago

Hi @alexblack, can you see this exception consistently? If so, is it possible for you to upload a sample project for us to debug, Thanks.

alexblack commented 9 years ago

Hi @wangmengyan95 unfortunately I don't really know how to repro this, but it might go away once https://github.com/ParsePlatform/Parse-SDK-Android/issues/203 is resolved.

Basically when the ParseInstallation fails to save (it looks like due to a race condition you guys have committed a fix for), then I retry, and encounter this issue.

The app is using the latest Parse android SDK.

wangmengyan95 commented 9 years ago

Hi @alexblack, I try my best but I still can not repo this issue. grantland has already sent a PR #214 to fix #203. Let's whether it solve your problem. If not, I will help you to fix this.

alexblack commented 9 years ago

hi @wangmengyan95 sounds good, whats the best way for me to try the fix - wait for the next SDK release?

wangmengyan95 commented 9 years ago

@alexblack, Grantland has already landed his PR so you can verify whether it works with the snapshot version of SDK. But make sure you do not use the snapshot SDK in your real production.

hatpick commented 7 years ago

@wangmengyan95 I get the same error in a totally different scenario while pinning a new custom class after a call to ParseObject.pinAll and ParseObject.saveAll to save many custom class objects and having them offline in the local datastore as well. #541