Mehrere Application Contexte

0 views
Skip to first unread message

rattakresch

unread,
Apr 17, 2008, 11:53:39 AM4/17/08
to Spring User Group Germany
Hallo,

Ich entwickle momentan eine Art Benchmark-Framework für JPA. Dazu will
ich unter anderem unter Spring verschiedene Kombinationen von JPA-
Providern (Hibernate, TopLink, OpenJPA) mit verschiedenen Datenbanken
(bisher PostgreSQL und MySQL) benchmarken. Dabei soll auf einem Client
eine Kombination gewählt werden, die entsprechende Bean von einem
Server geholt und berechnet werden.

Um die Transaktionssteuerung per Annotation (<tx:annotation-driven>)
verwenden zu können habe ich drei verschiedene Server, einen je JPA-
Provider erstellt. Nun hatte ich vor, jedem Server verschiedene
Application Contexte zu verpassen, und zwar einen je Datenbank. Die
Server sehen nun z.B. so aus:

public class RunSpringOpenJpaServer {

public static void main(String[] args) {

ApplicationContext ctxPostgres = new
ClassPathXmlApplicationContext("postgres-beans.xml");
ApplicationContext ctxMySQL = new
ClassPathXmlApplicationContext("mysql-beans.xml");
}
}

Das ganze funktioniert mit Hibernate und OpenJPA hervorragend. Mit
TopLink jedoch nicht, der Benchmark wird in der falschen Datenbank
durchgeführt.

Mein Frage wäre jetzt erstmal generell, ob das Design so sinnvoll ist,
ober ob es da eine schlauere Möglichkeit gibt. Da noch mehr Provider
und Datenbanken dazu kommen können, möchte ich eigentlich nicht für
jede Kombination einen Server haben. Wichtig wäre vielleicht nochmal
zu sagen, dass an einer Transaktion nur eine Datenbank beteiligt ist,
JTA ist meiner Meinung nach also nicht vonnöten.


Gruß,
Sebastian

rattakresch

unread,
Apr 18, 2008, 4:39:37 AM4/18/08
to Spring User Group Germany
Update:

Beim debuggen fällt mir auf, dass im TopLink-Fall der zuerst gesetzte
ApplicationContext auf active=true steht und der zweite auf false.
Bei Hibernate und OpenJPA stehen beide auf true. Hier mal ein
exemplarischer Context:

<beans xmlns=....>

<bean id="benchmarkImpl"
class="com.denkwerk.jbt.server.spring.BenchmarkBeanImpl"/>

<bean id="benchmarkRMI"
class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="mysqlBenchmark"/>
<property name="service" ref="benchmarkImpl" />
<property name="serviceInterface"
value="com.denkwerk.jbt.server.spring.SpringBenchmarkBean" />
<property name="registryPort" value="1399" />
</bean>


<!-- Entity Manager -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDS"/>

<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/
>
</property>

<property name="jpaVendorAdapter">
<bean
class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter">
<property name="database" value="MYSQL"></property>
<property name="generateDdl" value="true"></property>
<property name="showSql" value="false"></property>
</bean>
</property>
</bean>

<!-- TransactionManager -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<!-- Datasource -->
<bean name="mysqlDS"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></
property>
<property name="url" value="jdbc:mysql://url"></property>
<property name="username" value="xyz"></property>
<property name="password" value="xyz"></property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"></
bean>

</beans>

eberhar...@springsource.com

unread,
Apr 18, 2008, 12:35:33 PM4/18/08
to su...@googlegroups.com

Eberhard Wolff

unread,
Apr 19, 2008, 2:57:53 AM4/19/08
to su...@googlegroups.com, Spring User Group Germany
Hi,
um eine Bemerkung einzuwerfen: Du benutzt Load Time Weaving, um die Klassen durch den JPA Provider ändern lassen zu können. Da alle Tests wahrscheinlich dieselben persitenten Objekte verwenden, kann es gut sein, dass Chaos entsteht, weil alle JPA-Implementierungen die Klassen ändern wollen. Wahrscheinlich reicht eine Aufteilung nur in verschiedene ApplicationContexte nicht aus, sondern man muss auch verschiedene ClassLoader haben oder ohne Load Time Weaving arbeiten.
Gruß,
Eberhard

----- "rattakresch" <ratta...@googlemail.com> wrote:

--
Eberhard Wolff
Regional Director
SpringSource (Interface21 GmbH)
Sitz der Gesellschaft: Brentanostr. 52a - D-12163 Berlin
Geschäftsführer: Steven Schuurman, Rod Johnson
Amtsgericht Charlottenburg - HRB 103773 B

http://www.springsource.com

Author, "Spring - Framework für die Java Entwicklung"
http://www.spring-buch.de/

Founding Member Java Champions
https://java-champions.dev.java.net/

Phone: +49 178 414 61 62
Mail: eberhar...@interface21.com
Skype: ebr.wolff
Blog: http://JandIandMe.blogspot.com/
Mailing List: http://www.springsource.com/news-de

rattakresch

unread,
Apr 21, 2008, 9:14:02 AM4/21/08
to Spring User Group Germany
So,

das ursprüngliche Problem schein gelöst, ich habe mittels
<property name="persistenceXmlLocation" value="classpath:META-INF/.../
persistence.xml"/>
jeder Datenbank eine eigene persistence.xml spendiert. Jetz lassen
sich sogar alle JPA-Provider parallel in einem Server betreiben, wenn
jede Kombination einen eigenen ApplicationContext bekommt.

Danke für den Hinweis mit dem Load Time Weaving. Ich habe allerdings
bislang keine Unstimmigkeiten festgestellt. Die Frage ist, ob ich das
überhaupt anders konfigurieren kann, da ich ja nur Spring alleine und
keinen separaten Container benutze.

Gruß,
Sebastian
Reply all
Reply to author
Forward
0 new messages