Перемещено из списка рассылки Lift для потомков ( источник здесь ):
Я могу пролить немного света на то, как мы используем JPA. Я не уверен, что это за
контейнер, с которым вы работаете, но мы используем JBoss 4.2.2, и
используя свой пул подключений.
Мы используем библиотеку scalajpa для инициализации содержимого JPA и сохранения
ссылка на менеджер сущностей в локальной переменной потока. Мы
в частности, не используйте Lift RequestVarEM, потому что жизненный цикл
RequestVar несколько сложнее, чем обычный HTTP-запрос,
и это может привести к тому, что соединения не будут возвращены в пул в
своевременная мода.
Первый шаг - создать «модель» и указать ее имя
из вашего файла persistence.xml:
object MyDBModel extends LocalEMF("unitName", false) with
ThreadLocalEM
И мы создали небольшой код, чтобы упростить некоторые операции.
Каждый из наших постоянных классов смешивается в a, который обеспечивает некоторые базовые JPA
операции:
trait Persistent {
def persist = DBModel.persist(this)
def merge = DBModel.merge(this)
def remove = DBModel.remove(this)
}
Например,
@Entity
@Table{val name="person"}
class Person extends Persistent {
@Id
var id:String = _
@Column {val name="first_name", val nullable = false, val
updatable=false}
var firstName:String = _
@Column {val name="last_name", val nullable = false, val
updatable=false}
var lastName:String = _
@OneToMany{ ... }
var roles:Set[Role] = new HashSet[Role]()
// etc.
}
Мы в основном используем сопоставленные коллекции для навигации по объектной модели,
и поместить более сложные методы базы данных в объект-компаньон, чтобы
у нас нет ссылок на MyDBModel, разбросанных по всему коду
(как вы заметили, нежелательная практика). Например:
object Person {
def findByLastName = MyDBModel.createQuery[Person]
("...").findAll.toList
// etc.
}
Наконец, наша интеграция с Lift представлена в виде небольшого кода, который
упаковывает каждый запрос:
S.addAround(new LoanWrapper {
def apply[T](f: => T):T = {
try {
f
}
catch {
case e => MyDBModel.getTransaction.setRollbackOnly
}
finally {
MyDBModel.cleanup
}
}
})
Я оставил здесь некоторую обработку ошибок, чтобы прояснить идею, но
намерение состоит в том, что каждый HTTP-запрос выполняется в транзакции, которая
либо удастся, либо не получится полностью. Поскольку MyDBModel является
инициализируется при первом касании, в вашем тестовом коде вы можете настроить
EM, как вы считаете нужным, и объекты данных изолированы от этого
конфигурации.
Надеюсь, это полезно.
Шон