Merge "NOT NULL constraint by @NonNull" into oc-support-26.0-dev am: 4a16fdef70
am: 6c72e20a6c

Change-Id: Ic5794fc799e1809e63fe67c17efb814fd3435807
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
index 87846e3..09b6221 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
@@ -41,6 +41,11 @@
     return MoreElements.isAnnotationPresent(this, klass.java)
 }
 
+fun Element.isNonNull() =
+        asType().kind.isPrimitive
+                || hasAnnotation(android.support.annotation.NonNull::class)
+                || hasAnnotation(org.jetbrains.annotations.NotNull::class)
+
 /**
  * Checks if it has all of the annotations
  */
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/EmbeddedField.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/EmbeddedField.kt
index c6af79a..55e9cc4 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/EmbeddedField.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/EmbeddedField.kt
@@ -42,4 +42,8 @@
             return parent.isDescendantOf(other)
         }
     }
+
+    fun isNonNullRecursively(): Boolean {
+        return field.nonNull && (parent == null || parent.isNonNullRecursively())
+    }
 }
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt
index 1bfeaee..ee6f8a1 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/vo/Field.kt
@@ -16,6 +16,7 @@
 
 package android.arch.persistence.room.vo
 
+import android.arch.persistence.room.ext.isNonNull
 import android.arch.persistence.room.ext.typeName
 import android.arch.persistence.room.migration.bundle.FieldBundle
 import android.arch.persistence.room.parser.SQLTypeAffinity
@@ -41,6 +42,9 @@
     var cursorValueReader: CursorValueReader? = null
     val typeName: TypeName by lazy { type.typeName() }
 
+    /** Whether the table column for this field should be NOT NULL */
+    val nonNull = element.isNonNull() && (parent == null || parent.isNonNullRecursively())
+
     /**
      * Used when reporting errors on duplicate names
      */
@@ -106,15 +110,17 @@
      * definition to be used in create query
      */
     fun databaseDefinition(autoIncrementPKey : Boolean) : String {
-        val columnSpec = if (autoIncrementPKey) {
-            " PRIMARY KEY AUTOINCREMENT"
-        } else {
-            ""
+        val columnSpec = StringBuilder("")
+        if (autoIncrementPKey) {
+            columnSpec.append(" PRIMARY KEY AUTOINCREMENT")
+        }
+        if (nonNull) {
+            columnSpec.append(" NOT NULL")
         }
         return "`$columnName` ${(affinity ?: SQLTypeAffinity.TEXT).name}$columnSpec"
     }
 
     fun toBundle(): FieldBundle = FieldBundle(pathWithDotNotation, columnName,
-            affinity?.name ?: SQLTypeAffinity.TEXT.name
+            affinity?.name ?: SQLTypeAffinity.TEXT.name, nonNull
     )
 }
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt
index 8da4c12..e27600a 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/TableInfoValidationWriter.kt
@@ -45,10 +45,11 @@
             addStatement("final $T $L = new $T($L)", columnListType, columnListVar,
                     columnListType, entity.fields.size)
             entity.fields.forEachIndexed { index, field ->
-                addStatement("$L.put($S, new $T($S, $S, $L))",
+                addStatement("$L.put($S, new $T($S, $S, $L, $L))",
                         columnListVar, field.columnName, RoomTypeNames.TABLE_INFO_COLUMN,
                         /*name*/ field.columnName,
                         /*type*/ field.affinity?.name ?: SQLTypeAffinity.TEXT.name,
+                        /*nonNull*/ field.nonNull,
                         /*pkeyPos*/ entity.primaryKey.fields.indexOf(field) + 1)
             }
 
diff --git a/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java b/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
index 8ed676b..0846dff 100644
--- a/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
+++ b/room/compiler/src/test/data/databasewriter/output/ComplexDatabase.java
@@ -23,9 +23,9 @@
     protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration configuration) {
         final SupportSQLiteOpenHelper.Callback _openCallback = new RoomOpenHelper(configuration, new RoomOpenHelper.Delegate() {
             public void createAllTables(SupportSQLiteDatabase _db) {
-                _db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`uid` INTEGER, `name` TEXT, `lastName` TEXT, `ageColumn` INTEGER, PRIMARY KEY(`uid`))");
+                _db.execSQL("CREATE TABLE IF NOT EXISTS `User` (`uid` INTEGER NOT NULL, `name` TEXT, `lastName` TEXT, `ageColumn` INTEGER NOT NULL, PRIMARY KEY(`uid`))");
                 _db.execSQL("CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)");
-                _db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"d4b1d59e1344d0db40fe2cd3fe64d02f\")");
+                _db.execSQL("INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"6773601c5bcf94c71ee4eb0de04f21a4\")");
             }
 
             public void dropAllTables(SupportSQLiteDatabase _db) {
@@ -52,10 +52,10 @@
 
             protected void validateMigration(SupportSQLiteDatabase _db) {
                 final HashMap<String, TableInfo.Column> _columnsUser = new HashMap<String, TableInfo.Column>(4);
-                _columnsUser.put("uid", new TableInfo.Column("uid", "INTEGER", 1));
-                _columnsUser.put("name", new TableInfo.Column("name", "TEXT", 0));
-                _columnsUser.put("lastName", new TableInfo.Column("lastName", "TEXT", 0));
-                _columnsUser.put("ageColumn", new TableInfo.Column("ageColumn", "INTEGER", 0));
+                _columnsUser.put("uid", new TableInfo.Column("uid", "INTEGER", true, 1));
+                _columnsUser.put("name", new TableInfo.Column("name", "TEXT", false, 0));
+                _columnsUser.put("lastName", new TableInfo.Column("lastName", "TEXT", false, 0));
+                _columnsUser.put("ageColumn", new TableInfo.Column("ageColumn", "INTEGER", true, 0));
                 final HashSet<TableInfo.ForeignKey> _foreignKeysUser = new HashSet<TableInfo.ForeignKey>(0);
                 final TableInfo _infoUser = new TableInfo("User", _columnsUser, _foreignKeysUser);
                 final TableInfo _existingUser = TableInfo.read(_db, "User");
@@ -65,7 +65,7 @@
                             + " Found:\n" + _existingUser);
                 }
             }
-        }, "d4b1d59e1344d0db40fe2cd3fe64d02f");
+        }, "6773601c5bcf94c71ee4eb0de04f21a4");
         final SupportSQLiteOpenHelper.Configuration _sqliteConfig = SupportSQLiteOpenHelper.Configuration.builder(configuration.context)
                 .name(configuration.name)
                 .version(1923)
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt
index d00ff0c..9bfc0e7 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt
@@ -33,6 +33,7 @@
         const val ENTITY_PREFIX = """
             package foo.bar;
             import android.arch.persistence.room.*;
+            import android.support.annotation.NonNull;
             @Entity%s
             public class MyEntity %s {
             """
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
index 798b0be..34c522e 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
@@ -323,6 +323,21 @@
         }.compilesWithoutError().withWarningCount(0)
     }
 
+    @Test
+    fun notNull() {
+        singleEntity(
+                """
+                @PrimaryKey int id;
+                @NonNull public String name;
+                """
+        ) { entity, _ ->
+            val field = fieldsByName(entity, "name").first()
+            assertThat(field.name, `is`("name"))
+            assertThat(field.columnName, `is`("name"))
+            assertThat(field.nonNull, `is`(true))
+        }.compilesWithoutError()
+    }
+
     private fun fieldsByName(entity : Pojo, vararg fieldNames : String) : List<Field> {
         return fieldNames
                 .map { name -> entity.fields.find { it.name == name } }
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
index b21903c..0a5026a 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/PojoProcessorTest.kt
@@ -45,6 +45,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
 import simpleRun
 import javax.lang.model.element.Element
@@ -431,10 +432,13 @@
                     FieldProcessor.BindingScope.TWO_WAY, null).process()
             assertThat(pojo5, sameInstance(pojo4))
 
+            val type = invocation.context.COMMON_TYPES.STRING
+            val mockElement = mock(Element::class.java)
+            doReturn(type).`when`(mockElement).asType()
             val fakeField = Field(
-                    element = mock(Element::class.java),
+                    element = mockElement,
                     name = "foo",
-                    type = invocation.context.COMMON_TYPES.STRING,
+                    type = type,
                     affinity = SQLTypeAffinity.TEXT,
                     columnName = "foo",
                     parent = null,
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/QueryMethodProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/QueryMethodProcessorTest.kt
index 3474441..f7affbc 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/QueryMethodProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/QueryMethodProcessorTest.kt
@@ -46,6 +46,7 @@
 import com.squareup.javapoet.TypeName
 import com.squareup.javapoet.TypeVariableName
 import createVerifierFromEntities
+import mockElementAndType
 import org.hamcrest.CoreMatchers.`is`
 import org.hamcrest.CoreMatchers.instanceOf
 import org.hamcrest.CoreMatchers.notNullValue
@@ -55,7 +56,6 @@
 import org.junit.runner.RunWith
 import org.junit.runners.Parameterized
 import org.mockito.Mockito
-import javax.lang.model.element.Element
 import javax.lang.model.type.DeclaredType
 import javax.lang.model.type.TypeKind.INT
 import javax.lang.model.type.TypeMirror
@@ -77,10 +77,11 @@
         fun getParams() = arrayOf(true, false)
 
         fun createField(name: String, columnName: String? = null): Field {
+            val (element, type) = mockElementAndType()
             return Field(
-                    element = Mockito.mock(Element::class.java),
+                    element = element,
                     name = name,
-                    type = Mockito.mock(TypeMirror::class.java),
+                    type = type,
                     columnName = columnName ?: name,
                     affinity = null
             )
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/test_util.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/test_util.kt
index 89cea44..cd30c21 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/test_util.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/test_util.kt
@@ -31,18 +31,19 @@
 import android.arch.persistence.room.testing.TestProcessor
 import android.arch.persistence.room.verifier.DatabaseVerifier
 import android.arch.persistence.room.writer.ClassWriter
-import android.arch.persistence.room.writer.EntityCursorConverterWriter
 import com.google.auto.common.MoreElements
 import com.google.common.truth.Truth
 import com.google.testing.compile.CompileTester
 import com.google.testing.compile.JavaFileObjects
 import com.google.testing.compile.JavaSourcesSubjectFactory
 import com.squareup.javapoet.ClassName
-import com.squareup.javapoet.TypeSpec
 import org.mockito.Mockito
+import org.mockito.Mockito.doReturn
+import org.mockito.Mockito.mock
 import java.io.File
 import javax.lang.model.element.Element
-import javax.lang.model.element.Modifier
+import javax.lang.model.type.TypeKind
+import javax.lang.model.type.TypeMirror
 import javax.tools.JavaFileObject
 
 object COMMON {
@@ -126,3 +127,15 @@
     return DatabaseVerifier.create(invocation.context, Mockito.mock(Element::class.java),
             entities)!!
 }
+
+/**
+ * Create mocks of [Element] and [TypeMirror] so that they can be used for instantiating a fake
+ * [android.arch.persistence.room.vo.Field].
+ */
+fun mockElementAndType(): Pair<Element, TypeMirror> {
+    val element = mock(Element::class.java)
+    val type = mock(TypeMirror::class.java)
+    doReturn(TypeKind.DECLARED).`when`(type).kind
+    doReturn(type).`when`(element).asType()
+    return element to type
+}
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/verifier/DatabaseVerifierTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/verifier/DatabaseVerifierTest.kt
index df8afce..604c50f 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/verifier/DatabaseVerifierTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/verifier/DatabaseVerifierTest.kt
@@ -36,6 +36,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
+import org.mockito.Mockito.doReturn
 import org.mockito.Mockito.mock
 import simpleRun
 import java.sql.Connection
@@ -203,8 +204,10 @@
     }
 
     private fun field(name: String, type: TypeMirror, affinity: SQLTypeAffinity): Field {
+        val element = mock(Element::class.java)
+        doReturn(type).`when`(element).asType()
         val f = Field(
-                element = mock(Element::class.java),
+                element = element,
                 name = name,
                 type = type,
                 columnName = name,
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/vo/IndexTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/vo/IndexTest.kt
index 29d82d8..c1ac029 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/vo/IndexTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/vo/IndexTest.kt
@@ -17,14 +17,12 @@
 package android.arch.persistence.room.vo
 
 import android.arch.persistence.room.parser.SQLTypeAffinity
+import mockElementAndType
 import org.hamcrest.CoreMatchers
 import org.hamcrest.MatcherAssert
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.junit.runners.JUnit4
-import org.mockito.Mockito.mock
-import javax.lang.model.element.Element
-import javax.lang.model.type.TypeMirror
 
 @RunWith(JUnit4::class)
 class IndexTest {
@@ -45,11 +43,12 @@
     }
 
     private fun mockField(columnName : String): Field {
+        val (element, type) = mockElementAndType()
         return Field(
-                element = mock(Element::class.java),
+                element = element,
                 name = columnName + "_field",
                 affinity = SQLTypeAffinity.TEXT,
-                type = mock(TypeMirror::class.java),
+                type = type,
                 columnName = columnName
         )
     }
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt
index b3fe832..26efb4b 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt
@@ -63,7 +63,8 @@
             val query = SQLiteOpenHelperWriter(database)
                     .createQuery(database.entities.first())
             assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
-                    " `MyEntity` (`uuid` TEXT, `name` TEXT, `age` INTEGER, PRIMARY KEY(`uuid`))"))
+                    " `MyEntity` (`uuid` TEXT, `name` TEXT, `age` INTEGER NOT NULL," +
+                    " PRIMARY KEY(`uuid`))"))
         }.compilesWithoutError()
     }
 
@@ -79,7 +80,7 @@
             val query = SQLiteOpenHelperWriter(database)
                     .createQuery(database.entities.first())
             assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
-                    " `MyEntity` (`uuid` TEXT, `name` TEXT, `age` INTEGER," +
+                    " `MyEntity` (`uuid` TEXT, `name` TEXT, `age` INTEGER NOT NULL," +
                     " PRIMARY KEY(`uuid`, `name`))"))
         }.compilesWithoutError()
     }
@@ -97,8 +98,8 @@
             val query = SQLiteOpenHelperWriter(database)
                     .createQuery(database.entities.first())
             assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
-                    " `MyEntity` (`uuid` INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    " `name` TEXT, `age` INTEGER)"))
+                    " `MyEntity` (`uuid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
+                    " `name` TEXT, `age` INTEGER NOT NULL)"))
         }.compilesWithoutError()
     }
 
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.BooksDatabase/1.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.BooksDatabase/1.json
index 7f4ab82..dd056e2 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.BooksDatabase/1.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.BooksDatabase/1.json
@@ -2,26 +2,29 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "4ea44fe58127a3ea1d2b0d9f6155e91d",
+    "identityHash": "64fa560604c57044726b190dadbd8258",
     "entities": [
       {
         "tableName": "Book",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT, `title` TEXT, `bookPublisherId` TEXT, PRIMARY KEY(`bookId`), FOREIGN KEY(`bookPublisherId`) REFERENCES `Publisher`(`publisherId`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT NOT NULL, `title` TEXT NOT NULL, `bookPublisherId` TEXT NOT NULL, PRIMARY KEY(`bookId`), FOREIGN KEY(`bookPublisherId`) REFERENCES `Publisher`(`publisherId`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
         "fields": [
           {
             "fieldPath": "bookId",
             "columnName": "bookId",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           },
           {
             "fieldPath": "title",
             "columnName": "title",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           },
           {
             "fieldPath": "bookPublisherId",
             "columnName": "bookPublisherId",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           }
         ],
         "primaryKey": {
@@ -47,17 +50,19 @@
       },
       {
         "tableName": "Author",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`authorId` TEXT, `name` TEXT, PRIMARY KEY(`authorId`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`authorId` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`authorId`))",
         "fields": [
           {
             "fieldPath": "authorId",
             "columnName": "authorId",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           }
         ],
         "primaryKey": {
@@ -71,17 +76,19 @@
       },
       {
         "tableName": "Publisher",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`publisherId` TEXT, `name` TEXT, PRIMARY KEY(`publisherId`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`publisherId` TEXT NOT NULL, `name` TEXT NOT NULL, PRIMARY KEY(`publisherId`))",
         "fields": [
           {
             "fieldPath": "publisherId",
             "columnName": "publisherId",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           }
         ],
         "primaryKey": {
@@ -95,17 +102,19 @@
       },
       {
         "tableName": "BookAuthor",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT, `authorId` TEXT, PRIMARY KEY(`bookId`, `authorId`), FOREIGN KEY(`bookId`) REFERENCES `Book`(`bookId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`authorId`) REFERENCES `Author`(`authorId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT NOT NULL, `authorId` TEXT NOT NULL, PRIMARY KEY(`bookId`, `authorId`), FOREIGN KEY(`bookId`) REFERENCES `Book`(`bookId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, FOREIGN KEY(`authorId`) REFERENCES `Author`(`authorId`) ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED)",
         "fields": [
           {
             "fieldPath": "bookId",
             "columnName": "bookId",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           },
           {
             "fieldPath": "authorId",
             "columnName": "authorId",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": true
           }
         ],
         "primaryKey": {
@@ -144,7 +153,7 @@
     ],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"4ea44fe58127a3ea1d2b0d9f6155e91d\")"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"64fa560604c57044726b190dadbd8258\")"
     ]
   }
 }
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/1.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/1.json
index fba47c4..e05f095 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/1.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/1.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/2.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/2.json
index db6af46..8982d4f 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/2.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/2.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,17 +31,19 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/3.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/3.json
index 4d9dcb3..3bf0f03 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/3.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/3.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,22 +31,25 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/4.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/4.json
index 7bc6842..e899a02 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/4.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/4.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,22 +31,25 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -62,17 +67,20 @@
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "removedInV5",
             "columnName": "removedInV5",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/5.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/5.json
index c7d2dd1..801fdb5 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/5.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/5.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,22 +31,25 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -57,17 +62,19 @@
       },
       {
         "tableName": "Entity3",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/6.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/6.json
index a31ad21..a6fdf5b 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/6.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/6.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,22 +31,25 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json
index 33a7d1f..78ce189 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.migration.MigrationDbKotlin/7.json
@@ -2,21 +2,23 @@
   "formatVersion": 1,
   "database": {
     "version": 7,
-    "identityHash": "885b872dd8718be5726ae37479ad74e0",
+    "identityHash": "5653c29453937d8e34dc031af1ab4c7d",
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -39,22 +41,25 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -68,17 +73,19 @@
       },
       {
         "tableName": "Entity4",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -105,7 +112,7 @@
     ],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"885b872dd8718be5726ae37479ad74e0\")"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"5653c29453937d8e34dc031af1ab4c7d\")"
     ]
   }
 }
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
index d55178c..eb1a9b8 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/migration/MigrationKotlinTest.kt
@@ -247,7 +247,7 @@
 
     internal val MIGRATION_1_2: Migration = object : Migration(1, 2) {
         override fun migrate(database: SupportSQLiteDatabase) {
-            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity2` (`id` INTEGER,"
+            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity2` (`id` INTEGER NOT NULL,"
                     + " `name` TEXT, PRIMARY KEY(`id`))")
         }
     }
@@ -261,14 +261,14 @@
 
     internal val MIGRATION_3_4: Migration = object : Migration(3, 4) {
         override fun migrate(database: SupportSQLiteDatabase) {
-            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3` (`id` INTEGER,"
+            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3` (`id` INTEGER NOT NULL,"
                     + " `removedInV5` TEXT, `name` TEXT, PRIMARY KEY(`id`))")
         }
     }
 
     internal val MIGRATION_4_5: Migration = object : Migration(4, 5) {
         override fun migrate(database: SupportSQLiteDatabase) {
-            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3_New` (`id` INTEGER,"
+            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3_New` (`id` INTEGER NOT NULL,"
                     + " `name` TEXT, PRIMARY KEY(`id`))")
             database.execSQL("INSERT INTO Entity3_New(`id`, `name`) "
                     + "SELECT `id`, `name` FROM Entity3")
@@ -287,7 +287,7 @@
         override fun migrate(database: SupportSQLiteDatabase) {
             database.execSQL("CREATE TABLE IF NOT EXISTS "
                     + MigrationDbKotlin.Entity4.TABLE_NAME
-                    + " (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`),"
+                    + " (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`),"
                     + " FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`)"
                     + " ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)")
         }
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/1.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/1.json
index fba47c4..e05f095 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/1.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/1.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/2.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/2.json
index db6af46..fc5a1b6 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/2.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/2.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,26 +31,29 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
           "columnNames": [
             "id"
           ],
-          "autoGenerate": false
+          "autoGenerate": true
         },
-        "indices": []
+        "indices": [],
+        "foreignKeys": []
       }
     ],
     "setupQueries": [
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/3.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/3.json
index 4d9dcb3..f4629da 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/3.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/3.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,31 +31,35 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `addedInV3` TEXT, `name` TEXT)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
           "columnNames": [
             "id"
           ],
-          "autoGenerate": false
+          "autoGenerate": true
         },
-        "indices": []
+        "indices": [],
+        "foreignKeys": []
       }
     ],
     "setupQueries": [
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/4.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/4.json
index 7bc6842..b5a0794 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/4.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/4.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,50 +31,57 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `addedInV3` TEXT, `name` TEXT)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
           "columnNames": [
             "id"
           ],
-          "autoGenerate": false
+          "autoGenerate": true
         },
-        "indices": []
+        "indices": [],
+        "foreignKeys": []
       },
       {
         "tableName": "Entity3",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `removedInV5` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `removedInV5` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "removedInV5",
             "columnName": "removedInV5",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/5.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/5.json
index c7d2dd1..367b1f2 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/5.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/5.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,45 +31,51 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `addedInV3` TEXT, `name` TEXT)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
           "columnNames": [
             "id"
           ],
-          "autoGenerate": false
+          "autoGenerate": true
         },
-        "indices": []
+        "indices": [],
+        "foreignKeys": []
       },
       {
         "tableName": "Entity3",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/6.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/6.json
index a31ad21..3468f5b 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/6.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/6.json
@@ -6,17 +6,19 @@
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -29,31 +31,35 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `addedInV3` TEXT, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `addedInV3` TEXT, `name` TEXT)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
           "columnNames": [
             "id"
           ],
-          "autoGenerate": false
+          "autoGenerate": true
         },
-        "indices": []
+        "indices": [],
+        "foreignKeys": []
       }
     ],
     "setupQueries": [
diff --git a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json
index 14a8707..93a9682 100644
--- a/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json
+++ b/room/integration-tests/testapp/schemas/android.arch.persistence.room.integration.testapp.migration.MigrationDb/7.json
@@ -2,21 +2,23 @@
   "formatVersion": 1,
   "database": {
     "version": 7,
-    "identityHash": "3e20645b9e4557e60301d30835f0d706",
+    "identityHash": "03ff272b825e27b5c15545c85fe1b845",
     "entities": [
       {
         "tableName": "Entity1",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`))",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`))",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -39,22 +41,25 @@
       },
       {
         "tableName": "Entity2",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `addedInV3` TEXT, `name` TEXT)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `addedInV3` TEXT, `name` TEXT)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "addedInV3",
             "columnName": "addedInV3",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -68,17 +73,19 @@
       },
       {
         "tableName": "Entity4",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`), FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
         "fields": [
           {
             "fieldPath": "id",
             "columnName": "id",
-            "affinity": "INTEGER"
+            "affinity": "INTEGER",
+            "notNull": true
           },
           {
             "fieldPath": "name",
             "columnName": "name",
-            "affinity": "TEXT"
+            "affinity": "TEXT",
+            "notNull": false
           }
         ],
         "primaryKey": {
@@ -105,7 +112,7 @@
     ],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"3e20645b9e4557e60301d30835f0d706\")"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"03ff272b825e27b5c15545c85fe1b845\")"
     ]
   }
 }
\ No newline at end of file
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java
index 5c9bcc7..e573de1 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java
@@ -23,6 +23,7 @@
 import android.arch.persistence.room.integration.testapp.dao.BlobEntityDao;
 import android.arch.persistence.room.integration.testapp.dao.PetCoupleDao;
 import android.arch.persistence.room.integration.testapp.dao.PetDao;
+import android.arch.persistence.room.integration.testapp.dao.ProductDao;
 import android.arch.persistence.room.integration.testapp.dao.SchoolDao;
 import android.arch.persistence.room.integration.testapp.dao.ToyDao;
 import android.arch.persistence.room.integration.testapp.dao.UserDao;
@@ -30,6 +31,7 @@
 import android.arch.persistence.room.integration.testapp.vo.BlobEntity;
 import android.arch.persistence.room.integration.testapp.vo.Pet;
 import android.arch.persistence.room.integration.testapp.vo.PetCouple;
+import android.arch.persistence.room.integration.testapp.vo.Product;
 import android.arch.persistence.room.integration.testapp.vo.School;
 import android.arch.persistence.room.integration.testapp.vo.Toy;
 import android.arch.persistence.room.integration.testapp.vo.User;
@@ -37,7 +39,7 @@
 import java.util.Date;
 
 @Database(entities = {User.class, Pet.class, School.class, PetCouple.class, Toy.class,
-        BlobEntity.class},
+        BlobEntity.class, Product.class},
         version = 1, exportSchema = false)
 @TypeConverters(TestDatabase.Converters.class)
 public abstract class TestDatabase extends RoomDatabase {
@@ -48,6 +50,7 @@
     public abstract PetCoupleDao getPetCoupleDao();
     public abstract ToyDao getToyDao();
     public abstract BlobEntityDao getBlobEntityDao();
+    public abstract ProductDao getProductDao();
 
     @SuppressWarnings("unused")
     public static class Converters {
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/ProductDao.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/ProductDao.java
new file mode 100644
index 0000000..417fb72
--- /dev/null
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/ProductDao.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.arch.persistence.room.integration.testapp.dao;
+
+import android.arch.persistence.room.Dao;
+import android.arch.persistence.room.Insert;
+import android.arch.persistence.room.integration.testapp.vo.Product;
+import android.support.annotation.NonNull;
+
+@Dao
+public interface ProductDao {
+
+    @Insert
+    long insert(@NonNull Product product);
+
+}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
index 7b03e43..aa297ed 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/migration/MigrationTest.java
@@ -201,8 +201,8 @@
                     7, false, new Migration(6, 7) {
                         @Override
                         public void migrate(SupportSQLiteDatabase database) {
-                            database.execSQL("CREATE TABLE Entity4 (`id` INTEGER, `name` TEXT,"
-                                    + " PRIMARY KEY(`id`))");
+                            database.execSQL("CREATE TABLE Entity4 (`id` INTEGER NOT NULL,"
+                                    + " `name` TEXT, PRIMARY KEY(`id`))");
                         }
                     });
         } catch (Throwable t) {
@@ -271,7 +271,7 @@
         @Override
         public void migrate(SupportSQLiteDatabase database) {
             database.execSQL("CREATE TABLE IF NOT EXISTS `Entity2` ("
-                    + "`id` INTEGER PRIMARY KEY AUTOINCREMENT,"
+                    + "`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,"
                     + " `name` TEXT)");
         }
     };
@@ -287,7 +287,7 @@
     private static final Migration MIGRATION_3_4 = new Migration(3, 4) {
         @Override
         public void migrate(SupportSQLiteDatabase database) {
-            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3` (`id` INTEGER,"
+            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3` (`id` INTEGER NOT NULL,"
                     + " `removedInV5` TEXT, `name` TEXT, PRIMARY KEY(`id`))");
         }
     };
@@ -295,7 +295,7 @@
     private static final Migration MIGRATION_4_5 = new Migration(4, 5) {
         @Override
         public void migrate(SupportSQLiteDatabase database) {
-            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3_New` (`id` INTEGER,"
+            database.execSQL("CREATE TABLE IF NOT EXISTS `Entity3_New` (`id` INTEGER NOT NULL,"
                     + " `name` TEXT, PRIMARY KEY(`id`))");
             database.execSQL("INSERT INTO Entity3_New(`id`, `name`) "
                     + "SELECT `id`, `name` FROM Entity3");
@@ -315,7 +315,7 @@
         @Override
         public void migrate(SupportSQLiteDatabase database) {
             database.execSQL("CREATE TABLE IF NOT EXISTS " + MigrationDb.Entity4.TABLE_NAME
-                    + " (`id` INTEGER, `name` TEXT, PRIMARY KEY(`id`),"
+                    + " (`id` INTEGER NOT NULL, `name` TEXT, PRIMARY KEY(`id`),"
                     + " FOREIGN KEY(`name`) REFERENCES `Entity1`(`name`)"
                     + " ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)");
         }
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
index d0daf44..2b4a0e9 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
@@ -17,11 +17,13 @@
 package android.arch.persistence.room.integration.testapp.test;
 
 import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.hasSize;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -29,10 +31,12 @@
 import android.arch.persistence.room.integration.testapp.TestDatabase;
 import android.arch.persistence.room.integration.testapp.dao.BlobEntityDao;
 import android.arch.persistence.room.integration.testapp.dao.PetDao;
+import android.arch.persistence.room.integration.testapp.dao.ProductDao;
 import android.arch.persistence.room.integration.testapp.dao.UserDao;
 import android.arch.persistence.room.integration.testapp.dao.UserPetDao;
 import android.arch.persistence.room.integration.testapp.vo.BlobEntity;
 import android.arch.persistence.room.integration.testapp.vo.Pet;
+import android.arch.persistence.room.integration.testapp.vo.Product;
 import android.arch.persistence.room.integration.testapp.vo.User;
 import android.arch.persistence.room.integration.testapp.vo.UserAndAllPets;
 import android.content.Context;
@@ -63,6 +67,7 @@
     private BlobEntityDao mBlobEntityDao;
     private PetDao mPetDao;
     private UserPetDao mUserPetDao;
+    private ProductDao mProductDao;
 
     @Before
     public void createDb() {
@@ -72,6 +77,7 @@
         mPetDao = db.getPetDao();
         mUserPetDao = db.getUserPetDao();
         mBlobEntityDao = db.getBlobEntityDao();
+        mProductDao = db.getProductDao();
     }
 
     @Test
@@ -84,6 +90,20 @@
     }
 
     @Test
+    public void insertNull() throws Exception {
+        @SuppressWarnings("ConstantConditions")
+        Product product = new Product(1, null);
+        Throwable throwable = null;
+        try {
+            mProductDao.insert(product);
+        } catch (Throwable t) {
+            throwable = t;
+        }
+        assertNotNull("Was expecting an exception", throwable);
+        assertThat(throwable, instanceOf(SQLiteConstraintException.class));
+    }
+
+    @Test
     public void insertDifferentEntities() throws Exception {
         User user1 = TestUtil.createUser(3);
         user1.setName("george");
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/Product.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/Product.java
new file mode 100644
index 0000000..a395aea
--- /dev/null
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/Product.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.arch.persistence.room.integration.testapp.vo;
+
+import android.arch.persistence.room.Entity;
+import android.arch.persistence.room.PrimaryKey;
+import android.support.annotation.NonNull;
+
+@Entity(tableName = "products")
+public class Product {
+
+    @PrimaryKey(autoGenerate = true)
+    public final int id;
+
+    @NonNull
+    public final String name;
+
+    public Product(int id, @NonNull String name) {
+        this.id = id;
+        this.name = name;
+    }
+}
diff --git a/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/EntityBundle.java b/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/EntityBundle.java
index fc39a6a..8980a3b 100644
--- a/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/EntityBundle.java
+++ b/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/EntityBundle.java
@@ -166,7 +166,7 @@
     }
 
     /**
-     * @return Creates the list of SQL queries that are necessary to create this entitiy.
+     * @return Creates the list of SQL queries that are necessary to create this entity.
      */
     public Collection<String> buildCreateQueries() {
         List<String> result = new ArrayList<>();
diff --git a/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/FieldBundle.java b/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/FieldBundle.java
index 3e8fd97..eb73d81 100644
--- a/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/FieldBundle.java
+++ b/room/migration/src/main/java/android/arch/persistence/room/migration/bundle/FieldBundle.java
@@ -34,11 +34,14 @@
     private String mColumnName;
     @SerializedName("affinity")
     private String mAffinity;
+    @SerializedName("notNull")
+    private boolean mNonNull;
 
-    public FieldBundle(String fieldPath, String columnName, String affinity) {
+    public FieldBundle(String fieldPath, String columnName, String affinity, boolean nonNull) {
         mFieldPath = fieldPath;
         mColumnName = columnName;
         mAffinity = affinity;
+        mNonNull = nonNull;
     }
 
     public String getFieldPath() {
@@ -52,4 +55,8 @@
     public String getAffinity() {
         return mAffinity;
     }
+
+    public boolean isNonNull() {
+        return mNonNull;
+    }
 }
diff --git a/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java b/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
index 76effde..c6eade5 100644
--- a/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
+++ b/room/runtime/src/androidTest/java/android/arch/persistence/room/migration/TableInfoTest.java
@@ -56,8 +56,8 @@
                         + "name TEXT)");
         TableInfo info = TableInfo.read(mDb, "foo");
         assertThat(info, is(new TableInfo("foo",
-                toMap(new TableInfo.Column("id", "INTEGER", 1),
-                        new TableInfo.Column("name", "TEXT", 0)),
+                toMap(new TableInfo.Column("id", "INTEGER", false, 1),
+                        new TableInfo.Column("name", "TEXT", false, 0)),
                 Collections.<TableInfo.ForeignKey>emptySet())));
     }
 
@@ -68,8 +68,8 @@
                         + "name TEXT, PRIMARY KEY(name, id))");
         TableInfo info = TableInfo.read(mDb, "foo");
         assertThat(info, is(new TableInfo("foo",
-                toMap(new TableInfo.Column("id", "INTEGER", 2),
-                        new TableInfo.Column("name", "TEXT", 1)),
+                toMap(new TableInfo.Column("id", "INTEGER", false, 2),
+                        new TableInfo.Column("name", "TEXT", false, 1)),
                 Collections.<TableInfo.ForeignKey>emptySet())));
     }
 
@@ -81,9 +81,9 @@
         mDb.execSQL("ALTER TABLE foo ADD COLUMN added REAL;");
         TableInfo info = TableInfo.read(mDb, "foo");
         assertThat(info, is(new TableInfo("foo",
-                toMap(new TableInfo.Column("id", "INTEGER", 0),
-                        new TableInfo.Column("name", "TEXT", 1),
-                        new TableInfo.Column("added", "REAL", 0)),
+                toMap(new TableInfo.Column("id", "INTEGER", false, 0),
+                        new TableInfo.Column("name", "TEXT", false, 1),
+                        new TableInfo.Column("added", "REAL", false, 0)),
                 Collections.<TableInfo.ForeignKey>emptySet())));
     }
 
@@ -93,7 +93,7 @@
                 "CREATE TABLE foo (name TEXT NOT NULL)");
         TableInfo info = TableInfo.read(mDb, "foo");
         assertThat(info, is(new TableInfo("foo",
-                toMap(new TableInfo.Column("name", "TEXT", 0)),
+                toMap(new TableInfo.Column("name", "TEXT", true, 0)),
                 Collections.<TableInfo.ForeignKey>emptySet())));
     }
 
@@ -104,7 +104,7 @@
         TableInfo info = TableInfo.read(mDb, "foo");
         assertThat(info, is(new TableInfo(
                 "foo",
-                toMap(new TableInfo.Column("name", "TEXT", 0)),
+                toMap(new TableInfo.Column("name", "TEXT", false, 0)),
                 Collections.<TableInfo.ForeignKey>emptySet())));
     }
 
@@ -175,7 +175,7 @@
         TableInfo info = TableInfo.read(mDb, "foo");
         assertThat(info, is(new TableInfo(
                 "foo",
-                toMap(new TableInfo.Column("n", "INTEGER", 0)),
+                toMap(new TableInfo.Column("n", "INTEGER", false, 0)),
                 Collections.<TableInfo.ForeignKey>emptySet())));
     }
 
diff --git a/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java b/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java
index c9d2021..bcd2e9e 100644
--- a/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java
+++ b/room/runtime/src/main/java/android/arch/persistence/room/util/TableInfo.java
@@ -150,13 +150,15 @@
             if (cursor.getColumnCount() > 0) {
                 int nameIndex = cursor.getColumnIndex("name");
                 int typeIndex = cursor.getColumnIndex("type");
+                int notNullIndex = cursor.getColumnIndex("notnull");
                 int pkIndex = cursor.getColumnIndex("pk");
 
                 while (cursor.moveToNext()) {
                     final String name = cursor.getString(nameIndex);
                     final String type = cursor.getString(typeIndex);
+                    final boolean notNull = 0 != cursor.getInt(notNullIndex);
                     final int primaryKeyPosition = cursor.getInt(pkIndex);
-                    columns.put(name, new Column(name, type, primaryKeyPosition));
+                    columns.put(name, new Column(name, type, notNull, primaryKeyPosition));
                 }
             }
         } finally {
@@ -209,6 +211,10 @@
          */
         public final String type;
         /**
+         * Whether or not the column can be NULL.
+         */
+        public final boolean notNull;
+        /**
          * The position of the column in the list of primary keys, 0 if the column is not part
          * of the primary key.
          * <p>
@@ -224,9 +230,10 @@
         public final int primaryKeyPosition;
 
         // if you change this constructor, you must change TableInfoWriter.kt
-        public Column(String name, String type, int primaryKeyPosition) {
+        public Column(String name, String type, boolean notNull, int primaryKeyPosition) {
             this.name = name;
             this.type = type;
+            this.notNull = notNull;
             this.primaryKeyPosition = primaryKeyPosition;
         }
 
@@ -242,8 +249,9 @@
                 if (isPrimaryKey() != column.isPrimaryKey()) return false;
             }
 
-            //noinspection SimplifiableIfStatement
             if (!name.equals(column.name)) return false;
+            //noinspection SimplifiableIfStatement
+            if (notNull != column.notNull) return false;
             return type != null ? type.equalsIgnoreCase(column.type) : column.type == null;
         }
 
@@ -260,6 +268,7 @@
         public int hashCode() {
             int result = name.hashCode();
             result = 31 * result + (type != null ? type.hashCode() : 0);
+            result = 31 * result + (notNull ? 1231 : 1237);
             result = 31 * result + primaryKeyPosition;
             return result;
         }
@@ -269,6 +278,7 @@
             return "Column{"
                     + "name='" + name + '\''
                     + ", type='" + type + '\''
+                    + ", notNull=" + notNull
                     + ", primaryKeyPosition=" + primaryKeyPosition
                     + '}';
         }
diff --git a/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java b/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
index 16df7f1..aea3e96 100644
--- a/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
+++ b/room/testing/src/main/java/android/arch/persistence/room/testing/MigrationTestHelper.java
@@ -315,7 +315,7 @@
 
     private static TableInfo.Column toColumn(EntityBundle entity, FieldBundle field) {
         return new TableInfo.Column(field.getColumnName(), field.getAffinity(),
-                findPrimaryKeyPosition(entity, field));
+                field.isNonNull(), findPrimaryKeyPosition(entity, field));
     }
 
     private static int findPrimaryKeyPosition(EntityBundle entity, FieldBundle field) {