Невозможно получить список вложенных объектов внутри вложенного объекта в модели с помощью SkinnyORM - PullRequest
1 голос
/ 06 июня 2019

У меня есть модель Контакт с hasMany отношение к модели Роль. Модель Role имеет отношение hasManyThrough к телефону с промежуточной таблицей RolePhone. Все действия по извлечению установлены как активные.

Когда я получаю контакт, я вижу его список ролей, но у каждой роли есть пустой список телефонов. Но когда я получаю все роли, их списки телефонов содержат нужные телефоны.

Отношения помечены по умолчанию как в Контакте, так и в Роли, и я попытался вручную установить Role's joinDefinitions enabledEvenIfAssociated = true, но ни один из них не сработал

Это мои модели, показывающие только структуры и отношения

case class Contact(id: Long, name: String, roles: Seq[Role] = Nil)

object Contact extends SkinnyCRUDMapper[Contact] {
  hasMany[Role](
    Role -> Role.defaultAlias,
    (contact, role) => sqls.eq(contact.id, role.contactId),
    (contact, roles) => contact.copy(roles = roles),
  ).byDefault
}

case class RoleCommand(name: String, phoneNumbers: Seq[Int])

case class Role(id: Long, name: String, contactId: Long, phones: Seq[Phone] = Nil)

object Role extends SkinnyCRUDMapper[Role] {
  hasManyThrough[RolePhone, Phone](
    through = RolePhone -> RolePhone.defaultAlias,
    throughOn = (r, rp) => sqls.eq(r.id, rp.roleId),
    many = Phone -> Phone.defaultAlias,
    on = (rp, p) => sqls.eq(rp.phoneId, p.id),
    merge = (role, phones) => role.copy(phones = phones)
  ).byDefault
}

case class RolePhone(roleId: Long, phoneId: Long)
case class Phone(id: Long, number: Int)

Это моя структура базы данных

create table contact (
  id bigint(20) not null auto_increment primary key,
  name varchar(50) not null unique
) engine=innoDB;

create table role (
  id bigint(20) not null auto_increment primary key,
  name varchar(50) not null unique,
  contact_id bigint(20) not null
) engine=innoDB;

create table phone (
  id bigint(20) not null auto_increment primary key,
  number int(20) not null
) engine=innoDB;

create table role_phone (
  role_id bigint(20) not null,
  phone_id bigint(20) not null
) engine=innoDB;

И это главный класс, добавленный для выявления проблемы

object Main extends App with Connection with DatasourceConfig  {

  val contact1 = Contact.save("contact1",
    Seq(
      RoleCommand("role1", Seq(12345, 12321)),
      RoleCommand("role2", Seq(54321, 12321)),
      RoleCommand("role3", Seq(12345, 54321)),
    )
  )

  // retrieving a contact won't fill the phones number inside each role
  println(s"My Contact: ${Contact.findById(contact1)}")

  // retrieving a role will fill the phones list
  println(s"All Roles: ${Role.findAll()}")

}

Полный код на https://github.com/airabinovich/testing_skinny

Я ожидал, что при получении Контакта в каждой роли появится список телефонов. Следуя приведенному выше примеру, он должен выглядеть следующим образом

Contact(
  1,
  contact1,
  Vector(
    Role(1,role1,1,Vector(Phone(1,12345), Phone(2,12321))),
    Role(2,role2,1,Vector(Phone(3,54321), Phone(2,12321))),
    Role(3,role3,1,Vector(Phone(1,12345), Phone(3,54321)))
  )
)

Но я понял

Contact(
  1,
  contact1,
  Vector(
    Role(1,role1,1,List()),
    Role(1,role1,1,List()),
    Role(2,role2,1,List()),
    Role(2,role2,1,List()),
    Role(3,role3,1,List()),
    Role(3,role3,1,List())
  )
)

1 Ответ

0 голосов
/ 03 июля 2019

Когда Kazuhiro Sera ответил в своем запросе на получение ответа , можно быстро выполнить загрузку, немного изменив соотношение

object Contact extends SkinnyCRUDMapper[Contact] {
  val rolesRef = hasMany[Role](
    Role -> Role.defaultAlias,
    (contact, role) => sqls.eq(contact.id, role.contactId),
    (contact, roles) => contact.copy(roles = roles),
  ).includes[Role](
    merge = (contacts, roles) => contacts.map(c => c.copy(roles = roles.filter(_.contactId == c.id)))
   ).byDefault
}

и при извлечении из базы данных включают отношение

 println(s"My Contact: ${Contact.includes(Contact.rolesRef).findById(contact1)}")
...