Kalıcılık.xml'de <class> öğelerine ihtiyacım var mı?


110

Çok basit persistance.xml dosyam var:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    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">

    <persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
        <class>pl.michalmech.eventractor.domain.User</class>
        <class>pl.michalmech.eventractor.domain.Address</class>
        <class>pl.michalmech.eventractor.domain.City</class>
        <class>pl.michalmech.eventractor.domain.Country</class>

        <properties>
            <property name="hibernate.hbm2ddl.auto" value="validate" />
            <property name="hibernate.show_sql" value="true" />
        </properties>
    </persistence-unit>

</persistence>

ve çalışıyor.

Ancak <class>öğeleri kaldırdığımda, uygulama varlıkları görmüyor (tüm sınıflara açıklama ekleniyor @Entity).

@EntitySınıfları taramak için herhangi bir otomatik mekanizma var mı ?

Yanıtlar:


78

Kalıcılık.xml dosyasında jar-filekullanabileceğiniz bir vardır. Gönderen Java EE 5 öğretici :

<persistence>
    <persistence-unit name="OrderManagement">
        <description>This unit manages orders and customers.
            It does not rely on any vendor-specific features and can
            therefore be deployed to any persistence provider.
        </description>
        <jta-data-source>jdbc/MyOrderDB</jta-data-source>
        <jar-file>MyOrderApp.jar</jar-file>
        <class>com.widgets.Order</class>
        <class>com.widgets.Customer</class>
    </persistence-unit>
</persistence>

Bu dosya, OrderManagementJTA uyumlu bir veri kaynağı kullanan bir kalıcılık birimi tanımlar jdbc/MyOrderDB. jar-fileVe classvarlık sınıfları, gömülebilir sınıfları ve eşlenen süper sınıf: elementler kalıcılık yönetilen sınıfları belirtin. jar-fileİken, sınıflar kalıcılık yönetilen içeren paketlenmiş sebat birimi tarafından görülebilir eleman belirtir JAR dosyaları classeleman adı açıkça sınıflar kalıcılık başardı.

Hazırda Bekletme durumunda, Bölüm2'ye bir göz atın . Daha fazla ayrıntı için kurulum ve yapılandırma da.

DÜZENLEME: Aslında, spesifikasyonlarla uyumlu olmamaktan çekinmezseniz, Hazırda Bekletme, Java SE'de bile otomatik algılamayı destekler. Bunu yapmak için hibernate.archive.autodetectionmülkü ekleyin :

<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
  <!-- This is required to be spec compliant, Hibernate however supports
       auto-detection even in JSE.
  <class>pl.michalmech.eventractor.domain.User</class>
  <class>pl.michalmech.eventractor.domain.Address</class>
  <class>pl.michalmech.eventractor.domain.City</class>
  <class>pl.michalmech.eventractor.domain.Country</class>
   -->

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

    <property name="hibernate.hbm2ddl.auto" value="validate" />
    <property name="hibernate.show_sql" value="true" />
  </properties>
</persistence-unit>

13
Anlıyorum, ancak varlıklar (@Entity) ayrı Maven projesinde, bu nedenle jar dosyası adı her derlemede değişebilir. Belirli bir pakette veya sınıf yolunda taranacak bir şey arıyorum. Kalıcılık.xml dosyasında birçok <class> öğesi yazmak için tembelim.
Michał Mech

Her yapıda mı ?! Neden diye sormayacağım ama ... bunu çözmek için filtrelemeyi kullanabilirsiniz.
Pascal Thivent

Herkes tam olarak değil ama değişikliklere karşı dirençli olmak istiyorum.
Michal Mech

5
Eski iş parçacığı, biliyorum ama jpa-maven-eklentisine bir bakın .
Laird Nelson

Kalıcılık.xml'de <mapping-file> öğesini (varlıkların listesini içeren) kullanabilirsiniz, böylece kullanılan dosyaların aynı adını koruyabilir ve bunları başvurulan kavanozların yapısına entegre edebilirsiniz.
med_alpa

44

In Java SE çevre, şartname tarafından tüm sınıfları belirtmek zorunda yaptın gibidir:

Taşınabilirliği güvence altına almak için Java SE ortamlarında tüm adlandırılmış yönetilen kalıcılık sınıflarının bir listesi belirtilmelidir

ve

Kalıcılık biriminin kökünde bulunan açıklamalı kalıcılık sınıflarının kalıcılık birimine dahil edilmesi amaçlanmıyorsa, listeden çıkarılmış sınıfları dışlama öğesi kullanılmalıdır. Listelenmemiş sınıfları dışlama öğesi, Java SE ortamlarında kullanılmak üzere tasarlanmamıştır.

(JSR-000220 6.2.1.6)

In Java EE ortamlar, değil mi sizin için ek açıklamaları için sağlayıcı taramaları olarak bunu yapmak zorunda.

Resmi olmayan bir şekilde, <exclude-unlisted-classes>false</exclude-unlisted-classes>persistence.xml dosyanızda ayarlamayı deneyebilirsiniz . Bu parametre varsayılan olarak falseEE ve trueSE'dedir. Hem EclipseLink hem de Toplink bunu anlayabildiğim kadarıyla destekliyor. Ancak, yukarıda belirtildiği gibi, spesifikasyona göre SE'de çalıştığına güvenmemelisiniz.

Aşağıdakileri deneyebilirsiniz (SE ortamlarında çalışabilir veya çalışmayabilir):

<persistence-unit name="eventractor" transaction-type="RESOURCE_LOCAL">
     <exclude-unlisted-classes>false</exclude-unlisted-classes>

    <properties>
            <property name="hibernate.hbm2ddl.auto" value="validate" />
            <property name="hibernate.show_sql" value="true" />
    </properties>
</persistence-unit>

2
<exclude-unlisted-classes>false</exclude-unlisted-classes>WildFly ile çalışmadı 8.2.1. Final + Hibernate 4.3.7
Andreas Dietrich

12

Kalıcılık.xml'de Sınıf öğelerine ihtiyacım var mı?

Hayır, gerek yok. İşte Eclipse'de bunu nasıl yapıyorsunuz (Kepler test edildi):

Sağ tıklayıp, projenin tıklayın Özellikler ' seçeneğini JPA içinde, Sebat sınıf yönetimi kene Discover otomatik sınıfları açıklamalı .

görüntü açıklamasını buraya girin


9
Neden olumlu oy vermelisiniz? OP, Eclipse'den bahsetmiyor bile ve bu cevap, bu Eclipse özelliğinin kaputun altında ne yaptığını göstermiyor, böylece bir IDE olmadan bunu yapabilir.
Artem Novikov

2
@Artem Novikov: Bunu zor buluyorum çünkü soru çoğu zaman farklı ortamlardan kaynaklanıyor ve burada yardım etmek veya yararlı ipuçları vermek istiyoruz! (benim için olduğu gibi) Eclipse bu şekilde geliştirme için ortak bir IDE olduğundan ve başlık altında çok önemli olmadığı için yararlıdır, ancak sanırım tüm ilgili çalışma alanı projelerini içerecektir (örneğin, projem bağlıdır).
Andreas Dietrich

stackoverflow.com/questions/17951297/… güzel bir numara, ancak görünüşe göre bu yalnızca varlıklar persistence.xml ile aynı sınıf yükleyicide sona
ererse işe yarıyor

@abbas Lütfen persistence.xmlEclipse'in ürettiğini gösterin .
Frans

12

İlkbaharda JPA çalıştıranlar için sürüm 3.1'den itibaren, packagesToScanözelliği altında ayarlayabilir LocalContainerEntityManagerFactoryBeanve kalıcılık.xml'den tamamen kurtulabilirsiniz.

İşte aşağılık


Benim için çalıştı! Senaryo ilkbahar 4 + hazırda bekletme + jpa2 + maven idi. JUnit testi varlıklarımı bulmadı ama bu ayarla işi yaptı.
Cts

8

jar-fileDerlenmiş sınıflara sahip bir klasöre öğe yolu sağlayabilirsiniz . Örneğin, bazı entegrasyon testlerine persistence.xml'i hazırlarken şöyle bir şey ekledim:

 <jar-file>file:../target/classes</jar-file>

Aradığım şey buydu!
xtian

EclipseLink ile de çalışır!
Bombe

8

JPA 2+ için hile yapar

 <jar-file></jar-file>

açıklamalı @Entity sınıfları için savaştaki tüm kavanozları tara


2
bunun hakkında daha fazla bilgin var mı? bu kazara mı çalışıyor yoksa şartnamede yazılı mı? Uygulamaya bağlı mı?
markus

Tarayıcı AbstractScannerImpl uzanan sınıfta, hazırda bekletme - hiçbir fikri olmadığını 's hatanın veya özellik, üzgünüm
eriskooo

1
Hibernate 5.1.2.Final ile Java SE'de bu çözüm çalışmıyor. Hazırda bekletme bir jar dosya adı ( java.lang.IllegalArgumentException: Unable to visit JAR file:) bekliyor .
Stephan

1
İşler! :) WildFly ile 8.2.1. Final + Hibernate 4.3.7. Final
Andreas Dietrich

Thx adam, çok aradı ve bu mevcut en temiz çözüm. Wildfly10 + Hibernate 5.0.7 çalışıyor.
boutta

7

Hibernate, <exclude-unlisted-classes>false</exclude-unlisted-classes>SE altında desteklemez (başka bir poster bunun TopLink ve EclipseLink ile çalıştığından bahsetmiştir).

Kalıcılık.xml için sınıfların listesini otomatik olarak oluşturacak araçlar vardır, örneğin IntelliJ'de Veritabanı Şemasını İçe Aktar sihirbazı. Kalıcı.xml'de projenizin ilk sınıflarını aldıktan sonra, projeniz ilerledikçe tek tek sınıfları elle eklemek / kaldırmak basit olmalıdır.


Java SE'deki varlıkların otomatik olarak algılanması, JPA'nın bir parçası değildir. Buna dayanan uygulamalar taşınabilir değildir.
Pascal Thivent

4

Benim yaptığıma benzer bir şey yapıp yapmadığınızdan emin değilim, ama Maven kullanarak ayrı bir bileşende JAXB kullanarak bir XSD'den bir kaynak java yükü oluşturuyorum. Bu yapının "temel model" olarak adlandırıldığını varsayalım

Java kaynağını içeren bu yapıyı içe aktarmak ve "temel model" yapay kavanozumdaki tüm sınıflar üzerinde hazırda bekletme modunu çalıştırmak ve her birini açıkça belirtmek istemedim. Hazırda bekletme bileşenime bağımlılık olarak "temel model" ekliyorum, ancak sorun, kalıcılık.xml'deki etiketinin yalnızca mutlak yolları belirtmenize izin vermesidir.

Bunu aşma şeklim, "temel model" jar bağımlılığımı açık bir şekilde hedef dizinime kopyalamak ve aynı zamanda sürümünü çıkarmaktır. Dolayısıyla, "temel model" yapımı oluşturursam, "temel model-1.0-SNAPSHOT.jar" üretirken, kaynakları kopyala adımı onu "temel model.jar" olarak kopyalar.

Öyleyse hazırda bekletme bileşeni için pomunuzda:

            <!-- We want to copy across all our artifacts containing java code
        generated from our scheams. We copy them across and strip the version
        so that our persistence.xml can reference them directly in the tag
        <jar-file>target/dependency/${artifactId}.jar</jar-file> -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.5.1</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                </execution>
            </executions>       
            <configuration>
                <includeArtifactIds>base-model</includeArtifactIds>
                <stripVersion>true</stripVersion>
            </configuration>        
        </plugin>

Sonra bir sonraki aşamada hazırda bekletme eklentisini "işlem sınıfları" olarak adlandırıyorum:

            <!-- Generate the schema DDL -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>hibernate3-maven-plugin</artifactId>
            <version>2.2</version>

            <executions>
                <execution>
                    <id>generate-ddl</id>
                    <phase>process-classes</phase>
                    <goals>
                        <goal>hbm2ddl</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <components>
                    <component>
                        <name>hbm2java</name>
                        <implementation>annotationconfiguration</implementation>
                        <outputDirectory>/src/main/java</outputDirectory>
                    </component>
                </components>
                <componentProperties>
                    <persistenceunit>mysql</persistenceunit>
                    <implementation>jpaconfiguration</implementation>
                    <create>true</create>
                    <export>false</export>
                    <drop>true</drop>
                    <outputfilename>mysql-schema.sql</outputfilename>
                </componentProperties>
            </configuration>
        </plugin>

ve son olarak, kalıcılık.xml dosyamda kavanozun konumunu şu şekilde açıkça ayarlayabilirim:

<jar-file>target/dependency/base-model.jar</jar-file>

ve mülkü ekleyin:

<property name="hibernate.archive.autodetection" value="class, hbm"/>

3

Bu bir çözüm değil, Spring kullananlar için bir ipucu:

Ben kullanmaya çalıştı org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBeanayarıyla persistenceXmlLocationama bu sağlamak zorunda olan <class>(hatta eğer elemanları persistenceXmlLocationsadece işaret META-INF/persistence.xml).

Ne zaman değil kullanarak persistenceXmlLocationBunları ihmal olabilir <class>unsurları.


Ayarlarımda persistenceXmlLocationmülk kullandım LocalContainerEntityManagerFactoryBean. Ancak <class>öğeleri atlasam bile tüm sorgular çalışıyor . Spring / Hibernate / Maven uygulamasında. Ancak, "persistenceXmlLocation'ı kullanmadığımda, bu <class> öğelerini atlayabilirim" diyorsunuz . ama benim için tam tersi.
Lucky

@Ethan haklısınız, çünkü persistenceXmlLocation, packagesToScan'i geçersiz kılar - eğer kaynaklara bakarsanız. Bu nedenle, packagesToScan kullanırken bunu kullanmayın.
Artem Novikov

2

Bu çözümün şartnamede olduğundan emin değilim ama başkaları için paylaşabileceğimi düşünüyorum.

bağımlılık ağacı

my-entities.jar

Yalnızca varlık sınıflarını içerir. HayırMETA-INF/persistence.xml .

my-services.jar

Bağlıdır my-entities. Yalnızca EJB'leri içerir.

my-resources.jar

Bağlıdır my-services. Kaynak sınıflarını ve META-INF/persistence.xml.

sorunlar

  • Bir geçici bağımlılığın sürüm-sonradan eklenmiş artefakt adı olarak içindeki <jar-file/>elemanı nasıl belirtebiliriz my-resources?
  • <jar-file/>Öğenin değerini ve gerçek geçici bağımlılığın birini nasıl senkronize edebiliriz ?

çözüm

doğrudan (yedekli?) bağımlılık ve kaynak filtreleme

Bir mülk ve bir bağımlılık koydum my-resources/pom.xml.

<properties>
  <my-entities.version>x.y.z-SNAPSHOT</my-entities.version>
</properties>
<dependencies>
  <dependency>
    <!-- this is actually a transitive dependency -->
    <groupId>...</groupId>
    <artifactId>my-entities</artifactId>
    <version>${my-entities.version}</version>
    <scope>compile</scope> <!-- other values won't work -->
  </dependency>
  <dependency>
    <groupId>...</groupId>
    <artifactId>my-services</artifactId>
    <version>some.very.sepecific</version>
    <scope>compile</scope>
  </dependency>
<dependencies>

Şimdi persistence.xmlfiltrelenmeye hazır olun

<?xml version="1.0" encoding="UTF-8"?>
<persistence ...>
  <persistence-unit name="myPU" transaction-type="JTA">
    ...
    <jar-file>lib/my-entities-${my-entities.version}.jar</jar-file>
    ...
  </persistence-unit>
</persistence>

Maven Enforcer Eklentisi

İle dependencyConvergencekural, bunu temin ederim my-entities'versiyonu doğrudan ve geçişli hem de aynıdır.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <version>1.4.1</version>
  <executions>
    <execution>
      <id>enforce</id>
      <configuration>
        <rules>
           <dependencyConvergence/>
        </rules>
      </configuration>
      <goals>
        <goal>enforce</goal>
      </goals>
    </execution>
  </executions>
</plugin>

0

Her durumda zorunlu değildir.

Jboss 7.0.8 ve Eclipselink 2.7.0 kullanıyorum. Kalıcı.xml'de aynısını eklemeden varlıkları yükleme durumumda, Jboss Standalone XML'e aşağıdaki sistem özelliğini ekledim:

<property name="eclipselink.archive.factory" value="org.jipijapa.eclipselink.JBossArchiveFactoryImpl"/>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.