I found that @Insert method can return a long, which is the new rowId for the inserted item[1].
If the @Insert method receives only 1 parameter, it can return a long, which is the new rowId for the inserted item. If the parameter is an array or a collection, it should return long[] or List instead.
And SQLite documentation[2] says:
If a table contains a column of type INTEGER PRIMARY KEY, then that column becomes an alias for the ROWID. You can then access the ROWID using any of four different names, the original three names described above or the name given to the INTEGER PRIMARY KEY column. All these names are aliases for one another and work equally well in any context.
So we can make:
1) CompanyEntity.java
@Entity(tableName = "companies", indices = @Index(value = "name", unique = true)) public class CompanyEntity {
@PrimaryKey (autoGenerate = true)
public int id;
@NonNull
@ColumnInfo(name = "name")
private final String mCompanyName;
public CompanyEntity(@NonNull String companyName) {
mCompanyName = companyName;
}
@NonNull
public String getCompanyName() {
return mCompanyName;
}
}
2) EmployeeEntity.java
@Entity(tableName = "employee_list",
foreignKeys = @ForeignKey(
entity = CompanyEntity.class,
parentColumns = "id",
childColumns = "company_id",
onDelete = CASCADE),
indices = @Index("company_id"))
public class EmployeeEntity {
@PrimaryKey(autoGenerate = true)
public int id;
@ColumnInfo(name = "company_id")
private long mCompanyId;
@NonNull
@ColumnInfo(name = "name")
private final String mName;
public EmployeeEntity(@NonNull String name) {
mName = name;
}
@NonNull
public String getName() {
return mName;
}
public long getCompanyId() {
return mCompanyId;
}
public void setCompanyId(long companyId) {
mCompanyId = companyId;
}
}
3) EmployeeDao.java
@Dao
public abstract class EmployeeDao {
@Query("SELECT * FROM companies")
public abstract List<CompanyEntity> selectAllCompanies();
@Transaction
@Query("SELECT * FROM companies WHERE name LIKE :companyName")
public abstract List<CompanyEmployees> getEmployeesByCompanyName(String companyName);
@Transaction
public void insert(CompanyEntity companyEntity, List<EmployeeEntity> employeeEntities) {
// Save rowId of inserted CompanyEntity as companyId
final long companyId = insert(companyEntity);
// Set companyId for all related employeeEntities
for (EmployeeEntity employeeEntity : employeeEntities) {
employeeEntity.setCompanyId(companyId);
insert(employeeEntity);
}
}
// If the @Insert method receives only 1 parameter, it can return a long,
// which is the new rowId for the inserted item.
// https://developer.android.com/training/data-storage/room/accessing-data
@Insert(onConflict = REPLACE)
public abstract long insert(CompanyEntity company);
@Insert
public abstract void insert(EmployeeEntity employee);
}
It seems to work fine.
Full source code and example project:
https://github.com/relativizt/android-room-one-to-many-auto-pk
Links
- https://developer.android.com/training/data-storage/room/accessing-data
- https://www.sqlite.org/autoinc.html