2012-04-16 6 views
0

完全に空のデータベース/テーブルでキー制約が失敗したように見えます。私はすでにadbでデータベースをエクスポートしてsqlitemanでオープンしました。まだ空です。Androidの下のSQLite:空のデータベースの挿入/置換時に制約が失敗する[解決済み]

これは私のコードです:

public class DatabaseAdapterSystem extends SQLiteOpenHelper { 

    private Context context; 
    private static final int DATABASE_VERSION = 20; 
    private static final String DATABASE_NAME = "databaseSystem"; 

    public DatabaseAdapterSystem(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     this.context = context; 
    } 

    @Override 
    public void onOpen(SQLiteDatabase db) { 
     Log.d(getClass().getSimpleName(), "isReadOnly: " + db.isReadOnly()); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     try { 
      db.beginTransaction(); 
      db.execSQL(
       "CREATE TABLE \"accounts\" (" + 
        "\"userId\" INTEGER PRIMARY KEY NOT NULL, " + 
        "\"nickname\" TEXT NOT NULL, " + 
        "\"password\" TEXT NOT NULL, " + 
        "\"profileImageFileName\" TEXT NOT NULL " + 
       ")" 
      ); 
      db.setTransactionSuccessful(); 
     } 
     finally { 
      db.endTransaction(); 
     } 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     // Until yet no need 
    } 

    // ------------------------------------------------------------------------- 

    public synchronized BackendAccountList getAccounts() { 
     Log.d(getClass().getSimpleName(), "DatabaseAdapterSystem::getAccounts has been called"); 

     BackendAccountList result = new BackendAccountList(); 
     SQLiteDatabase db = null; 
     Cursor resultSet = null; 

     try { 
      db = this.getReadableDatabase(); 

      resultSet = db.query(
        "accounts", 
        new String[] {"userId", "nickname", "password", "profileImageFileName"}, // Columns 
        null,               // Selection 
        null,               // SelectionArgs 
        null,               // GroupBy 
        null,               // Having 
        "userId asc" 
        ); 

      if (resultSet != null) { 
       int colUserId = resultSet.getColumnIndex("userId"); 
       int colNickname = resultSet.getColumnIndex("nickname"); 
       int colPassword = resultSet.getColumnIndex("password"); 
       int colProfileImageFileName = resultSet.getColumnIndex("profileImageFileName"); 

       if (resultSet.moveToFirst()) { 
        do { 
         result.add(new BackendAccount(
            resultSet.getInt(colUserId), 
            resultSet.getString(colNickname), 
            resultSet.getString(colPassword), 
            resultSet.getString(colProfileImageFileName) 
           )); 
        } while (resultSet.moveToNext()); 
       } 
      } 
     } 
     finally { 
      if (resultSet != null) { 
       resultSet.close(); 
      } 
      if (db != null) { 
       db.close(); 
      } 
     } 
     return result; 
    } 

    public synchronized BackendAccountList putAccount(BackendAccount account) { 
     Log.d(getClass().getSimpleName(), "DatabaseAdapterSystem::putAccount has been called"); 

     BackendAccountList result = new BackendAccountList(); 
     SQLiteDatabase db = null; 

     try { 
      db = this.getWritableDatabase(); 
      ContentValues cv = new ContentValues(); 
      cv.put("userId", account.getUserId()); 
      cv.put("nickname", account.getUsername()); 
      cv.put("password", account.getPassword()); 
      cv.put("profileImageFileName", account.getProfileImage()); 
      db.insertOrThrow("accounts", null, cv); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     finally { 
      if (db != null) { 
       db.close(); 
      } 
     } 
     return result; 
    } 
} 

アプリは、アップロードされるgetAccountsが呼び出されるとBackendAccountsのリストを返した後。 通信が成功した後、データベースに新しいアカウントを格納するためにputAccountが呼び出されることがあります。

私はすでにreplaceOrThrowと試みたと思いますが、でもそれは制約に失敗した(エラー19)

//編集:スタックトレース

04-16 10:47:05.910: W/System.err(13130): android.database.sqlite.SQLiteConstraintException: error code 19: constraint failed 
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteStatement.native_execute(Native Method) 
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteStatement.execute(SQLiteStatement.java:66) 
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1426) 
04-16 10:47:05.910: W/System.err(13130): at android.database.sqlite.SQLiteDatabase.insertOrThrow(SQLiteDatabase.java:1308) 
04-16 10:47:05.910: W/System.err(13130): at com.jappy.service.DatabaseAdapterSystem.putAccount(DatabaseAdapterSystem.java:183) 
04-16 10:47:05.910: W/System.err(13130): at com.jappy.service.JappyService$1.handleMessage(JappyService.java:60) 
04-16 10:47:05.910: W/System.err(13130): at android.os.Handler.dispatchMessage(Handler.java:99) 
04-16 10:47:05.910: W/System.err(13130): at android.os.Looper.loop(Looper.java:123) 
04-16 10:47:05.920: W/System.err(13130): at android.app.ActivityThread.main(ActivityThread.java:4363) 
04-16 10:47:05.920: W/System.err(13130): at java.lang.reflect.Method.invokeNative(Native Method) 
04-16 10:47:05.920: W/System.err(13130): at java.lang.reflect.Method.invoke(Method.java:521) 
04-16 10:47:05.920: W/System.err(13130): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
04-16 10:47:05.920: W/System.err(13130): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
04-16 10:47:05.920: W/System.err(13130): at dalvik.system.NativeStart.main(Native Method) 

//編集 は、いずれかの列が(NULL含まprofileImageFilename)。それがsqliteがこのメッセージをスローした理由です。 問題が解決しました。

+0

エラーは何ですか?スタックトレースを送信します。 –

+1

まあ、4つのフィールドのうちの1つが「ヌル」です。それがどれであるかを見つけるためにいくつかのログを追加してください。 –

+0

そのような場合にsqliteがそのエラーをスローすることを知らなかった。ありがとう。 – pmedia

答えて

2

制約の1つに違反すると、SQLiteConstraintExceptionがスローされます。あなたのケースでは、4つのフィールドはすべて、nullに制限されています。したがって、これらのフィールドのいずれかにnullの値を挿入しようとすると、エラーが発生します。それがどれであるかを見つけるためにいくつかのログを追加してください。

関連する問題