2017.03.29 eBean Kotlin explicit "join" table example - GlenKPeterson/One-off_Examples GitHub Wiki

This is a more complicated many-to-many mapping using eBean and Kotlin where we store an additional item on the join table. Just like the simple many-to-many example, an author can write many books and a book can have many authors. This requires 3 database tables:

  • author stores authors
  • book stores books
  • book_author associates books with authors (many-to-many mapping table).

Now we are additionally going to store a "role" (editor, author, preface author, etc.) on the book_author relationship.

Goal (My)SQL

create table author (
  id                            bigint auto_increment not null,
  name                          varchar(255),
  constraint pk_author primary key (id)
);

create table book (
  id                            bigint auto_increment not null,
  title                         varchar(255),
  constraint pk_book primary key (id)
);

create table book_author (
  book_id                       bigint not null,
  author_id                     bigint not null,
  role                          varchar(255),
  constraint pk_book_author primary key (book_id,author_id)
);

It only requires 2 Kotlin classes (BaseModel just adds a surrogate key). Examples are tested with Kotlin 1.1.0 and eBean 8.2.1.

Kotlin

// Puts an ID field (surrogate key) on tables that extend this.
@MappedSuperclass
abstract class BaseModel {
    @Id var id:Long = 0
}

@Entity
class Author(@Column var name: String): BaseModel() {
    @OneToMany(mappedBy = "authors")
    val books:MutableList<Book> = mutableListOf()
}

@Entity
class Book(@Column var title:String) : BaseModel() {
    @OneToMany(mappedBy = "book") // mapped in both directions!
    val authors:MutableList<Author> = mutableListOf()
}

// TODO: Creates the right database table, but without the primary key.
// TODO: Can get these records with ebeanServer.find(BookAuthor.class)
// TODO: but can't with book.getBookAuthors()
@Entity
@Table(uniqueConstraints = arrayOf(UniqueConstraint(columnNames = arrayOf("book_id", "author_id"))))
class BookAuthorAssoc(@ManyToOne @Key val book:Book,
                      @ManyToOne @Key val author:Author) {
    @Column var role:String = ""
}

TODO: I have NOT gotten this to work! Because we added the role field, we now need to explicitly create a BookAuthor class in Kotlin.

⚠️ **GitHub.com Fallback** ⚠️