# Models

In DBFlow we dont have any restrictions on what your table class is. We do, however if you use Java, we recommend you subclass `BaseModel` on your highest-order base-class, which provides a default implementation for you. Otherwise utilize a kotlin extension method on `Any`.

```kotlin
myTableObject.save(db)
```

## Columns

By default, DBFlow inclusdes all properties as columns. For other kinds of fields, they must contain either `@PrimaryKey` or `@ForeignKey` to be used in tables. However this still requires you to specify at least one `@PrimaryKey` field. You can then explicitly ignore fields via the `@ColumnIgnore` annotation if necessary. You can turn off all fields and make it explicit using `@Table(allFields = false)`

In Kotlin, Column properties must be public and `var` for now. In future versions, we hope to support Kotlin constructors without default arguments. For now, all must be `var` and provide a default constructor. We respect nullability of the properties and won't assign `null` to them if they're not nullable, but they must provide a default value.

In Java, Columns can be `public`, package-private, or `private`. `private` fields **must** come with `public` java-bean-style getters and setters. Package private used in other packages generate a `_Helper` class which exposes a method to call these fields in an accessible way. This has some overhead, so consider making them with `public` get/set or public.

Here is an example of a "nice" `Table`:

```kotlin
@Table(database = AppDatabase::class)
class Dog(@PrimaryKey var id: Int = 0, var name: String? = null)
```

Columns have a wide-range of supported types in the `Model` classes: **Supported Types**:

1. all primitives including `Char`,`Byte`, `Short`, and `Boolean`.
2. All Kotlin nullable primitives (java boxed).
3. `String`, `Date`, `java.sql.Date`, `Calendar`, `com.dbflow5.data.Blob`, `Boolean`
4. Custom data types via a [TypeConverter](/dbflow/usage2/usage/typeconverters.md)
5. `Model` as fields, but only as `@PrimaryKey` and/or `@ForeignKey`
6. `@ColumnMap` objects that flatten an object into the current table. Just like a `@ForeignKey`, but without requiring a separate table. (4.1.0+). **Note:** Avoid nesting more than one object, as the column count could get out of control.

**Unsupported Types**:

1. `List<T>` : List columns are not supported and not generally proper for a relational database. However, you can get away with a non-generic `List` column via a `TypeConverter`. But again, avoid this if you can.
2. Anything that is generically typed (even with an associated `TypeConverter`). If you need to include the field, subclass the generic object and provide a `TypeConverter`.

## Inherited Columns

Since we don't require extension on `BaseModel` directly, tables can extend non-model classes and inherit their fields directly (given proper accessibility) via the `@InheritedColumn` annotation (or `@InheritedPrimaryKey` for primary keys):

```java
@Table(database = AppDatabase.class,
        inheritedColumns = {@InheritedColumn(column = @Column, fieldName = "name"),
                @InheritedColumn(column = @Column, fieldName = "number")},
        inheritedPrimaryKeys = {@InheritedPrimaryKey(column = @Column,
                primaryKey = @PrimaryKey,
                fieldName = "inherited_primary_key")})
public class InheritorModel extends InheritedModel implements Model {
```

**Note:** This implementation is not recommended for most users. If you do not control the type directly, the inherited class may change in incompatible ways.

## Primary Keys

DBFlow supports multiple primary keys, right out of the box. Simply create a table with multiple `@PrimaryKey`:

```kotlin
@Table(database = AppDatabase::class)
class Dog(@PrimaryKey var name: String = "", @PrimaryKey var breed: String = "")
```

If we want an auto-incrementing key, you specify `@PrimaryKey(autoincrement = true)`, but only one of these kind can exist in a table and you cannot mix with regular primary keys.

## Unique Columns

DBFlow has support for SQLite `UNIQUE` constraint (here for documentation)\[<http://www.tutorialspoint.com/sqlite/sqlite_constraints.htm>].

Add `@Unique` annotation to your existing `@Column` and DBFlow adds it as a constraint when the database table is first created. This means that once it is created you should not change or modify this.

We can *also* support multiple unique clauses in order to ensure any combination of fields are unique. For example:

To generate this in the creation query:

```
UNIQUE('name', 'number') ON CONFLICT FAIL, UNIQUE('name', 'address') ON CONFLICT ROLLBACK
```

We declare the annotations as such:

```kotlin
@Table(database = AppDatabase::class,
  uniqueColumnGroups = [@UniqueGroup(groupNumber = 1, uniqueConflict = ConflictAction.FAIL),
                        @UniqueGroup(groupNumber = 2, uniqueConflict = ConflictAction.ROLLBACK)])
class UniqueModel(
  @PrimaryKey @Unique(unique = false, uniqueGroups = [1,2])
  var name: String = "",
  @Column @Unique(unique = false, uniqueGroups = [1])
  var number: String = "",
  @Column @Unique(unique = false, uniqueGroups = [2])
  var address: String = "")
```

The `groupNumber` within each defined `uniqueColumnGroups` with an associated `@Unique` column. We need to specify `unique=false` for any column used in a group so we expect the column to be part of a group. If true as well, the column will *also* alone be unique.

## Default Values

**Not to be confused with Kotlin default values.** This only applies when fields are marked as `nullable`. When fields are non null in kotlin, we utilize the default constructor value when it is set, so when the column data is `null` from a `Cursor`, we do not override the initial assignment.

DBFlow supports default values in a slightly different way than SQLite does. Since we do not know exactly the intention of missing data when saving a `Model`, since we group all fields, `defaultValue` specifies a value that we replace when saving to the database when the value of the field is `null`.

This feature only works on Boxed primitive and the `DataClass` equivalent of objects (such as from TypeConverter), such as String, Integer, Long, Double, etc. **Note**: If the `DataClass` is a `Blob`, unfortunately this will not work. For `Boolean` classes, use "1" for true, "0" for false.

```kotlin
@Column(defaultValue = "55")
var count: Int,
@Column(defaultValue = "\"this is\"")
var test: String,
@Column(defaultValue = "1000L")
var date: Date,
@Column(defaultValue = "1")
var aBoolean: Boolean,
```

**Note:** DBFlow inserts its literal value into the `ModelAdapter` for the table so any `String` must be escaped.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dbflow.gitbook.io/dbflow/usage2/usage/models.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
