13 Stimmen

Entkopplung eines JPA entities jar von persistence.xml in SE-Umgebung

Gibt es eine Möglichkeit, ein Jar mit JPA-kommentierten Entitäten in mehr als einer SE-Anwendung wiederzuverwenden (als Abhängigkeit)? <jar-file> in persistence.xml wird in SE-Umgebungen nicht unterstützt, gibt es also eine andere Möglichkeit?

6voto

Pascal Thivent Punkte 548176

Offiziell (laut Spezifikation), müssen Sie alle Klassen mit der Option class Element . Ich zitiere das Kapitel 6.2.1.6 mapping-file, jar-file, class, exclude-unlisted-classes der JSR-220 :

Anstelle oder zusätzlich zu den JAR-Dateien und Mapping-Dateien kann auch eine Liste von benannten verwalteten Persistenzklassen angegeben werden. Alle Mapping-Metadaten-Annotationen, die zu diesen Klassen gefunden werden, werden verarbeitet, oder sie werden unter Verwendung der Mapping-Annotations-Standardwerte abgebildet. Die class Element wird verwendet, um eine verwaltete Persistenzklasse aufzulisten. Eine Liste aller benannten verwalteten Persistenzklassen muss in Java SE-Umgebungen angegeben werden, um die Portabilität zu gewährleisten . Portable Java SE-Anwendungen sollten sich nicht auf die anderen hier beschriebenen Mechanismen verlassen, um die verwalteten Persistenzklassen einer Persistenzeinheit zu spezifizieren. Persistenzanbieter können auch verlangen, dass die Menge der zu verwaltenden Entitätsklassen und Klassen vollständig in jeder der persistence.xml Dateien in Java SE-Umgebungen.

Wenn es Ihnen nichts ausmacht, nicht portabel zu sein, können Sie Hibernate unterstützt unter Verwendung der jar-file Element in Java SE (in diesem Fall wird eine absolute Url benötigt, nicht eine praktische). Hibernate unterstützt die automatische Erkennung sogar in JSE. Viel besser:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
  version="1.0">
  <persistence-unit name="foo">

    <!-- This is required to be spec compliant, Hibernate however supports auto-detection even in JSE. -->
    <class>foo.Bar<class>

    <properties>
      <!-- Scan for annotated classes and Hibernate mapping XML files -->
      <property name="hibernate.archive.autodetection" value="class, hbm"/>
      ...
    </properties>
  </persistence-unit>

</persistence>

2voto

David Holbrook Punkte 1617

Soweit ich weiß, gibt es keine Möglichkeit, die Klassensuche nach Anmerkungen in dieser Konfiguration zum Laufen zu bringen. Sie können jedoch explizit Ihre persistence.xml-Datei auf jede Entitätsklasse verweisen.

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
                     version="1.0">

  <persistence-unit name="punit">

    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <jta-data-source>java:/myDS</jta-data-source>

    <!-- Must be explicit as classes are in separate jar -->
    <class>com.foo.Bar</class>
    <class>com.foo.Baz</class>

    <properties/>      
  </persistence-unit>

</persistence>

2voto

Yaya Punkte 51

Nach meiner Erfahrung funktioniert es jetzt.

Wir verwenden: Hibernate3.jar 3.6.0.Final hibernate-jpa-2.0-api-1.0.0.Final.jar

El < jar-datei >Datei:...< /jar-datei > weiß, wie man nach relativen Pfaden sucht - und es funktioniert sowohl für jar-Dateien als auch für Verzeichnisse.

Ich benutze diese Fähigkeit zweimal:

  • mit einem Jar, das meine Entitäten enthält - die in mehreren Anwendungen verwendet werden. Jede Anwendung hat ihre eigene persistence.xml - hauptsächlich, um verschiedene ehcache-Einstellungen bereitzustellen.
  • Mit Junits möchte ich, dass alle meine Tests in allen anderen abhängigen Projekten eine einzige persistence.xml-Datei haben, die auf alle Entitäten im Entitäten-Projekt verweist. Dann wird die persistence.xml im Entities-Projekt unter test/resources/META-INF gespeichert und verweist auf das Bin-Verzeichnis dieses Projekts: < jar-file >Datei:../entities/bin< /jar-file >

1voto

MarkBM Punkte 11

Das war ein Problem, auf das ich gestoßen bin. Es ist etwas schwieriger, da ich mehrere Jars sowohl einzeln als auch als Teil eines Kriegseinsatzes ausführen muss.

Es gibt ein paar Hacks da draußen, die sich entweder um mehrere persistence.xml-Dateien und/oder um einen seltsam anmutenden Versuch zu drehen scheinen, die Jar-Datei mit Hilfe von Spring Resource Loaders zu referenzieren (was bei mir nicht funktionierte).

Mein persönlicher Hack ist die Verwendung von Spring Resource Loaders, um eine Ressource aufzulösen, die in allen Entity-Jars ist, analysieren Sie die URL-Jar-Referenz und verwenden Sie einen Spring Persistence Unit Manager, um diese in das Jar-File-Tag in der virtuellen Persistence.xml zu injizieren

Das ist zwar ein Umweg, vermeidet aber, dass es mehrere persistence.xml gibt - was technisch ungültig ist.

public class SpringPersistenceUnitManager extends DefaultPersistenceUnitManager implements ApplicationContextAware {

private final Logger log = LoggerFactory.getLogger(getClass());

private ApplicationContext ctx = null;

private String jarLocationPattern;

@Override
protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
    super.postProcessPersistenceUnitInfo(pui);
    try {
        Resource[] resources = ctx.getResources("classpath*:applicationContext.xml");
        for (Resource res : resources) {
            String resJar = resolveJar(res.getURL());
            if (!resJar.equals(pui.getPersistenceUnitRootUrl().toString())) {
                log.info("Adding " + resJar + " to persistence context");
                pui.addJarFileUrl(new URL(resJar));
            }
        }
    }
    catch (IOException e) {
        log.error("error", e);
    }
}

private String resolveJar(URL fileInJar) {
    String path = fileInJar.getPath();
    return path.substring(0, path.indexOf('!'));
}

und den Frühlingskontext:

<util:properties id="hibernate.properties" location="classpath:hibernate.properties" />

<bean id="persistenceUnitManager" class="com.rokksoft.blackice.util.SpringPersistenceUnitManager"
    p:defaultDataSource-ref="jdbcDataSourcePool"
/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" lazy-init="true"
    p:persistenceUnitManager-ref="persistenceUnitManager"
    p:persistenceUnitName="blackicePU"
    p:dataSource-ref="jdbcDataSourcePool"
    p:jpaProperties-ref="hibernate.properties">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
</bean>

Idealerweise sollten Sie die Jar-Namen filtern - ein 3rd-Party-Jar kann alles Mögliche enthalten.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X