2016-02-24 2 views
0

У меня возникли некоторые проблемы с Squeryl ORM. Очень простые функции, такие как выбор или вставка строк без отношений, отлично работают, проблемы возникают, когда я пытаюсь получить данные с соотношением 1: N в тривиальном сценарии. В тестовой БД я создаю две таблицы «Вопросы и ответы». Один вопрос может содержать несколько ответов. Вот создание таблиц SQL:Squeryl отношение 1: N

DROP TABLE IF EXISTS `questions`; 
CREATE TABLE `questions` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `nid` int(11) NOT NULL, 
    `text` text NOT NULL, 
    `active` tinyint(1) NOT NULL DEFAULT '1', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `questions` (`id`, `nid`, `text`, `active`) 
VALUES 
(1,1,'test question',1), 
(2,2,'second question',1); 

DROP TABLE IF EXISTS `answers`; 
CREATE TABLE `answers` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `question_id` int(11) unsigned NOT NULL, 
    `text` text NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `qwerty` (`question_id`), 
    CONSTRAINT `qwerty` FOREIGN KEY (`question_id`) REFERENCES `questions` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

INSERT INTO `answers` (`id`, `question_id`, `text`) 
VALUES 
(1,1,'test answer'); 

А вот Scala код с классами модели:

class BaseEntity extends KeyedEntity[Long] { val id: Long = 0 } 

class Question(var nid: Long, var text: String, 
     var active: Integer) extends BaseEntity { 

    def this() = this(0, "", 1) 
    lazy val Answers: List[Answer] = DataBase.answersToQuestion.left(this).toList 
} 

class Answer(var question_id: Long, var text: String) extends BaseEntity { 
    def this() = this(0, "") 
    lazy val Question: Question = DataBase.answersToQuestion.right(this).head 
} 

object DataBase extends Schema { 
    val questions = table[Question]("questions") 
    val answers = table[Answer]("answers") 
    val answersToQuestion = oneToManyRelation(questions, answers) 
     .via((q, a) => q.id === a.question_id) 

    on(answers)(a => declare(a.id is (autoIncremented))) 
    on(questions)(q => declare(q.id is (autoIncremented))) 
} 

Так по выбору данных я получаю полный объект Вопрос, но ответы всегда нуль.

var question: Option[Question] = inTransaction { DataBase.questions.lookup(1L) } 
//question.Answers is null !! 

Может кто-нибудь, пожалуйста, взглянуть на это и сказать мне, в чем моя ошибка?

+0

Есть ли ошибки, возвращенные из SQL в соединитель базы данных? Возможно, вы захотите начать там. – Squeegy

+0

Нет ошибок. Другие поля успешно получены – Greebo

ответ

0

Может быть, я просто надеюсь, что для другого поведения или неправильной ОРМ как-то, хотя я получаю пустой отладчик, но это отлично работает таким образом, для класса Ответ:

def getQuestion = inTransaction(Question.headOption) 

И этот способ Вопрос:

def getAnswers = inTransaction(Answers.toList) 

Надеюсь, это было бы полезно для тех, кто является новым для Squeryl и испытывает ту же проблему, что и я.

Не ставьте вопрос, как ответили до сих пор, возможно, есть лучшее решение.

+0

Все вызовы в базу данных должны произойти внутри транзакции, поэтому имеет смысл, что запрос ответов за пределами одного не будет работать. Я просто удивлен, что ошибки не было, поскольку Squeryl обычно бросал один. В любом случае, если вы удалите «ленивый», он, вероятно, также сработает для вас, хотя он будет заполнять это при поиске. В качестве альтернативы вы также можете добавить inTransaction в исходный объект - например: 'lazy val Answers: List [Answer] = inTransaction {DataBase.answersToQuestion.left (this) .toList}'. 'inTransaction' присоединяется к существующей транзакции, если таковая существует, поэтому вложение прекрасно – jcern

Смежные вопросы