2013-08-16 18 views
11

Próbuję utrzymywać tę samą jednostkę zarówno w bazach danych MySQL, jak i Postgres (chodzi przede wszystkim o zidentyfikowanie niespójności i opracować szczegóły wszelkich problemów związanych z podwójnym pisaniem - które Natknąłem się tutaj). Artykuły, które znalazłem, opisują rozwiązania zależne od dodatkowych frameworków. Próbuję rozwiązać ten problem, używając Glassfish 4.0 out-of-the-box, JPA 2.1 z EclipseLink 2.5 jako dostawcą JPA. Używam Eclipse i zdaję sobie sprawę, że IDE nie obsługuje konfigurowania wielu jednostek utrwalania w pliku persistence.xml, więc piszę o tym bezpośrednio XML.persistence.xml dla wielu jednostek trwałości

Spodziewałem się czegoś takiego w kodzie (w taki sam sposób):

@PersistenceContext(name = "MyAppMySQLPU") 
EntityManager emMySQL; 
@PersistenceContext(name = "MyAppPostgresPU") 
EntityManager emPostgres; 
//...etc... 
MyThing thing = new MyThing(); 
//...etc... 
emMySQL.persist(thing); 
emPostgres.persist(thing); 

i użyć pliku persistence.xml zawierający ten:

<persistence-unit name="MyAppPostgresPU"> 
    <jta-data-source>jdbc/PostgresPool_test</jta-data-source> 
    <class>model.MyThing</class> 
    </persistence-unit> 

    <persistence-unit name="MyAppMySQLPU"> 
    <jta-data-source>jdbc/MySQLPool_test</jta-data-source> 
    <class>model.MyThing</class> 
    </persistence-unit> 

Kiedy to zrobić, Uzyskaj następujący błąd:

SEVERE: Exception while invoking class org.glassfish.persistence.jpa.JPADeployer prepare method 
SEVERE: Exception while preparing the app 
SEVERE: Exception while preparing the app : Could not resolve a persistence unit corresponding to the persistence-context-ref-name [MyAppPostgresPU] in the scope of the module called [MyApp]. Please verify your application. 

Ale jeśli dołączę tylko jeden z <persistence-unit> zwrotów (nie ma znaczenia, który z nich), jednostka jest utrzymywana w powiązanej bazie danych - po prostu nie mogę wymyślić, jak zmusić ją do pracy z obydwoma w tym samym czasie (bez wykorzystania funkcjonalności utrwalania w dodatkowych frameworkach).

Odpowiedz

15

Gotowy do pracy; kilka rzeczy trzeba było zrobić. Wydaje się, że kluczową częścią tego jest to, że aby korzystać z wielu baz danych z podejściem, które stosowałem, należy ustawić typ puli połączeń, aby korzystać z transakcji rozproszonych. Ponieważ jest to w zasadzie eksperyment, obie bazy danych DB nie musiały być w tej samej transakcji, ale nie stanowi to problemu. (Artykuł This był pomocny w zidentyfikowaniu tego z komunikatów o błędach). Konieczna była również zmiana parametrów PostgreSQL zgodnie z opisem here, w celu umożliwienia przygotowania transakcji.


Ten dostał to wszystko dzieje:

(1) W GlassFish:
W pula połączeń JDBC, zmienić typ zasobu zarówno dla DB do javax.sql.XADataSource. Zmień nazwę klasy Datasource dla Postgres na org.postgresql.xa.PGXADataSource; zmień nazwę klasy DataSource dla MySQL na com.mysql.jdbc.jdbc2.optional.MysqlXADataSource.

(2) w konfiguracji Posgres (postgresql.config):
Włączenie max_prepared_transactions i ustawiony, że jest większy niż 1 max_connections. (Musiałem rozejrzeć się za obydwoma parametrami, aby znaleźć coś, co nie wysadziło całej dostępnej pamięci współdzielonej, ale ponieważ jest to tylko eksperyment, zmniejszająca się liczba połączeń db do rosnącej pamięci współdzielonej jest OK)

(3) w kodzie:
Zmień @PersistenceContext(name="...") do @PersistenceContext(unitName="...")


Zastrzeżenie na tej „odpowiedź” - większość z tego jest dla mnie nowe, więc to nie może być najbardziej elegancki sposób, aby sobie z tym poradzić. Jeśli ktokolwiek może zapewnić "najlepszą praktykę", aby rozwiązać ten problem, byłbym bardzo zainteresowany.

Powiązane problemy