Я борюсь с Play и JPA, чтобы иметь возможность использовать две разные модели javax.persistence.Entity, связанные с двумя разными единицами продолжительности (необходимо, чтобы иметь возможность подключаться к разным БД - например, Oracle и MySQL db).Play framework 2 + JPA с несколькими persistenceUnit
Проблема возникает из транзакции, которая всегда привязывается к JPA persitenceUnit по умолчанию (см. Параметр jpa.default).
Вот два действия контроллера, которые показывают решение, которое я нашел, чтобы определить постоянство вручную: контроллеры пакетов;
import models.Company;
import models.User;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;
import play.mvc.Controller;
import play.mvc.Result;
public class Application extends Controller {
//This method run with the otherPersistenceUnit
@Transactional(value="other")
public static Result test1() {
JPA.em().persist(new Company("MyCompany"));
//Transaction is run with the "defaultPersistenceUnit"
JPA.withTransaction(new play.libs.F.Callback0() {
@Override
public void invoke() throws Throwable {
JPA.em().persist(new User("Bobby"));
}
});
return ok();
}
//This action run with the otherPersistenceUnit
@Transactional
public static Result test2() {
JPA.em().persist(new User("Ryan"));
try {
JPA.withTransaction("other", false, new play.libs.F.Function0<Void>() {
public Void apply() throws Throwable {
JPA.em().persist(new Company("YourCompany"));
return null;
}
});
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
return ok();
}
}
Это решение не кажется действительно «чистым». Я хотел бы знать, знаете ли вы, что лучше избегать необходимости вручную изменять используемую транзакцию.
С этой целью я создал репо на git с рабочим образцовым приложением, которое показывает, как я настроил проект.
https://github.com/cm0s/play2-jpa-multiple-persistenceunit
Спасибо за вашу помощь
Вы правы, я также нашел решение с использованием JPA.em ("dbSource"). Однако решение не является совершенным. Реализация по умолчанию Play JPA Helper не дает возможности одновременно открывать более одного entityManager. Мне пришлось добавить какой-то хитрый код, чтобы иметь возможность переключать источник entityManager. –