@Entity(tableName = "teams")
public class TeamEntity implements Parcelable{

    @PrimaryKey @ColumnInfo(name = "team_id") protected String id;
    @ColumnInfo(name = "team_name") protected String name;

    public TeamEntity(String id, String name) {
        this.id = id;
        this.name = name;
        this.city = city;
    }
}


public class Team extends TeamEntity {

    @Relation(parentColumn = "team_id", entityColumn = "role_team_id", entity = RoleEntity.class)
    private List<Role> roles = new ArrayList<>();

    public Team(String id, String name) {
        super(id, name);
    }

    // This because of a room bug, it won't accept it in the constructor
    public void setRoles(List<Role> roles) {
        this.roles.clear();
        this.roles.addAll(roles);
    }
}

@Entity(tableName = "events",
        foreignKeys = @ForeignKey(entity = TeamEntity.class, parentColumns = "team_id", childColumns = "event_team_id")
)
public class EventEntity implements Parcelable {

    @PrimaryKey
    @ColumnInfo(name = "event_id") protected String id;
    @ColumnInfo(name = "event_name") protected String name;
    @ColumnInfo(name = "event_notes") protected String notes;
    @ColumnInfo(name = "event_team_id") protected String teamId;
    @ColumnInfo(name = "event_start_date") protected Date startDate;
    @ColumnInfo(name = "event_end_date") protected Date endDate;

    public EventEntity(String id, String name, String notes, String teamId, Date startDate, Date endDate) {
        this.id = id;
        this.name = name;
        this.notes = notes;
        this.teamId = teamId;
        this.startDate = startDate;
        this.endDate = endDate;
    }
}

public class Event extends EventEntity {

    @Embedded
    private Team team;

    public Event(String id, String name, String notes, Date startDate, Date endDate, Team team) {
        super(id, name, notes, team.getId(), startDate, endDate);
        this.team = team;
    }

    // This because of a room bug, it doesn't construct the Embedded team first thet set the roles on it,
    // it instead constructs the Team, Then constructs the Event then calls set Roles on the Event
    // instead of the team.
    public void setRoles(List<Role> roles){
        team.setRoles(roles);
    }
}

public class Role implements Parcelable {

    @PrimaryKey @ColumnInfo(name = "role_id") protected String id;
    @ColumnInfo(name = "role_name") protected String name;
    @ColumnInfo(name = "role_team_id") protected String teamId;
    @ColumnInfo(name = "role_image_url") protected String imageUrl;

    @Embedded protected User user;

    public RoleEntity(String id, String name, String teamId, String imageUrl, User user) {
        this.id = id;
        this.name = name;
        this.teamId = teamId;
        this.imageUrl = imageUrl;
        this.user = user;
    }
}

@Entity(
        tableName = "roles",
        foreignKeys = {
                @ForeignKey(entity = UserEntity.class, parentColumns = "user_id", childColumns = "user_id"),
                @ForeignKey(entity = TeamEntity.class, parentColumns = "team_id", childColumns = "role_team_id")
        }
)
public class Role {

    @PrimaryKey @ColumnInfo(name = "role_id") protected String id;
    @ColumnInfo(name = "role_name") protected String name;
    @ColumnInfo(name = "role_team_id") protected String teamId;
    @ColumnInfo(name = "role_image_url") protected String imageUrl;

    @Embedded protected User user;

    public Role(String id, String name, String teamId, String imageUrl, User user) {
        this.id = id;
        this.name = name;
        this.teamId = teamId;
        this.imageUrl = imageUrl;
        this.user = user;
    }
}

@Entity(tableName = "users")
public class User implements Parcelable {

    @PrimaryKey @ColumnInfo(name = "user_id") protected String id;
    @ColumnInfo(name = "user_first_name") protected String firstName;
    @ColumnInfo(name = "user_last_name") protected String lastName;

    public User(String id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
// EventDao_impl snippet, method should return a List of Events

public class EventDao_impl {

	void getEventsSnippet() {
		while(_cursor.moveToNext()) {
	        final Event _item;
	        final String _tmpId;
	        _tmpId = _cursor.getString(_cursorIndexOfId);
	        final String _tmpName;
	        _tmpName = _cursor.getString(_cursorIndexOfName);
	        final String _tmpNotes;
	        _tmpNotes = _cursor.getString(_cursorIndexOfNotes);
	        final Date _tmpStartDate;
	        final Long _tmp;
	        if (_cursor.isNull(_cursorIndexOfStartDate)) {
	          _tmp = null;
	        } else {
	          _tmp = _cursor.getLong(_cursorIndexOfStartDate);
	        }
	        _tmpStartDate = __dateTypeConverter.fromTimestamp(_tmp);
	        final Date _tmpEndDate;
	        final Long _tmp_1;
	        if (_cursor.isNull(_cursorIndexOfEndDate)) {
	          _tmp_1 = null;
	        } else {
	          _tmp_1 = _cursor.getLong(_cursorIndexOfEndDate);
	        }
	        _tmpEndDate = __dateTypeConverter.fromTimestamp(_tmp_1);
	        final Team _tmpTeam;
	        if (! (_cursor.isNull(_cursorIndexOfId_1) && _cursor.isNull(_cursorIndexOfName_1) && _cursor.isNull(_cursorIndexOfCity) && _cursor.isNull(_cursorIndexOfState) && _cursor.isNull(_cursorIndexOfZip) && _cursor.isNull(_cursorIndexOfImageUrl_1))) {
	          final String _tmpId_1;
	          _tmpId_1 = _cursor.getString(_cursorIndexOfId_1);
	          final String _tmpName_1;
	          _tmpName_1 = _cursor.getString(_cursorIndexOfName_1);
	          final String _tmpCity;
	          _tmpCity = _cursor.getString(_cursorIndexOfCity);
	          _tmpTeam = new Team(_tmpId_1,_tmpName_1,_tmpCity);
	        }  else  {
	          _tmpTeam = null;
	        }
	        _item = new Event(_tmpId,_tmpName,_tmpNotes,_tmpStartDate,_tmpEndDate,_tmpTeam);

	        // I whish I could ignore the teamId here as it's already called in the constructor
	        final String _tmpTeamId;
	        _tmpTeamId = _cursor.getString(_cursorIndexOfTeamId);
	        _item.setTeamId(_tmpTeamId);
	        //

	        if (!_cursor.isNull(_cursorIndexOfId_1)) {
	          final String _tmpKey = _cursor.getString(_cursorIndexOfId_1);
	          ArrayList<Role> _tmpCollection = _collectionTeamRoles.get(_tmpKey);
	          if(_tmpCollection == null) {
	            _tmpCollection = new ArrayList<Role>();
	            _collectionTeamRoles.put(_tmpKey, _tmpCollection);
	          }

	          // Why is set roles colled on the event and not the Team???
	          _item.setRoles(_tmpCollection);
	        }
	        _result.add(_item);
	      }
  	}
  }