```class Announcement(id: EntityID<Int>) : I...
# exposed
o
Copy code
class Announcement(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<Announcement>(AnnouncementsTable)

    var author by AnnouncementsTable.author
    var title by AnnouncementsTable.title
    var content by AnnouncementsTable.content
    var attachmentUrls by Attachment via AttachmentsTable
    var channel by AnnouncementsTable.channel
    var createdAt by AnnouncementsTable.createdAt
    var archivedAt by AnnouncementsTable.archivedAt
    var level by AnnouncementsTable.level
}

class Attachment(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<Attachment>(AttachmentsTable)

    var url by AttachmentsTable.url
}
These are the entities I have now, but I get the exception, table does not reference source
c
Hi @oSumAtrIX To enforce a many-to-one relation, a foreign key constraint needs to first be defined on the appropriate table. Since one announcement can have many attachments (and each attachment can only be linked to one announcement), this constraint needs to be applied to
AttachmentsTable
. A foreign key can be generated on table creation in Exposed using `reference()`:
Copy code
object AttachmentsTable : IntIdTable() {
    val url = varchar("url", 256)
    val announcement = reference("announcement", AnnouncementsTable)
}
// no changes needed for AnnouncementsTable
A corresponding field for this new column should be added to the entity
Attachment
so that you can insert/access the referenced announcement (and its fields):
Copy code
class Attachment(id: EntityID<Int>) : IntEntity(id) {
    companion object : IntEntityClass<Attachment>(AttachmentsTable)
    var url by AttachmentsTable.url
    var announcement by Announcement referencedOn AttachmentsTable.announcement
}
If you also want to get all attachments for a single announcement, you just need to adjust the
attachmentUrls
field in the
Announcement
entity class:
Copy code
val attachmentUrls by Attachment referrersOn AttachmentsTable.announcement
via
only comes into play for many-to-many relations that use a third intermediate table for reference storage.
o
Hi @Chantal Loncle and thank you for your response.
To create a new Attachment, do I have to separately create a new Attachment and reference the Announcement?
c
If the Announcement being referenced has already been created, it can be used directly in the new Attachment's property assignment block for insertion into the AttachmentsTable:
Copy code
val announcement1 = Announcement.new {
    author = "Author 1"
}
Attachment.new {
    url = "url 1"
    announcement = announcement1
}
Parent entities can also be created and referenced at the same time by nesting calls to
new()
in the child entity:
Copy code
Attachment.new {
    url = "url 2"
    announcement = Announcement.new {
        author = "Author 2"
    }
}
If you need to separately create a new Attachment and reference an Accouncement sometime after insertion, this means the relation column has to be nullable. So you'd have to use the optional variants of all the reference functions I mentioned previously, for example:
Copy code
object AttachmentsTable : IntIdTable() {
    val announcement: Column<EntityID<Int>?> = optReference("announcement", AnnouncementsTable)
    // equivalent to:
    // val announcement = reference("announcement", AnnouncementsTable).nullable()
}