ich auf Aviad Antwort addieren möchte zu beantworten scheint es wie pro OP Antrag zu vervollständigen .
Die Einbauten:
Um eine Instanz von MetadataImplementor zu bekommen, die Abhilfe ist, eine Instanz von SessionFactoryBuilderFactory durch Java ServiceLoader Anlage zu registrieren. Die Methode getSessionFactoryBuilder dieses registrierten Diensts wird dann von MetadataImplementor mit einer Instanz von sich aufgerufen, wenn Hibernate bootstrapped wird. Die Code-Referenzen sind unter:
- Service Loading
- Invocation of getSessionFactoryBuilder
also letztlich eine Instanz von MetadataImplementor zu bekommen, müssen Sie SessionFactoryBuilderFactory implementieren und registrieren, damit ServiceLoader diesen Service erkennen:
Eine Implementierung von SessionFactoryBuilderFactory:
public class MetadataProvider implements SessionFactoryBuilderFactory {
private static MetadataImplementor metadata;
@Override
public SessionFactoryBuilder getSessionFactoryBuilder(MetadataImplementor metadata, SessionFactoryBuilderImplementor defaultBuilder) {
this.metadata = metadata;
return defaultBuilder; //Just return the one provided in the argument itself. All we care about is the metadata :)
}
public static MetadataImplementor getMetadata() {
return metadata;
}
}
Um die oben zu schaffen einfache Textdatei im folgenden Pfad zu registrieren (vorausgesetzt, es ist ein Maven-Projekt, schließlich müssen wir die ‚META-INF‘ -Ordner in dem Classpath verfügbar sein):
src/main/resources/META-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory
Und der Inhalt der Textdatei sollte eine einzelne Zeile sein (kann sogar mehrere Zeilen sein, wenn Sie mehrere Instanzen registrieren müssen) und den vollständig qualifizierten Klassenpfad Ihrer Implementierung von SessionFactoryBuilderFactory angeben. Wenn beispielsweise für die oben genannte Klasse Ihr Paketname "com.IhreFirma.prj" lautet, sollte der Inhalt der Datei der folgende Inhalt sein.
com.yourcompany.prj.MetadataProvider
Und das ist es, wenn Sie Ihre Anwendung, Frühling App oder Standalone-Hibernate ausführen, werden Sie eine Instanz von MetadataImplementor zur Verfügung haben über eine statische Methode einmal überwintern bootstraped wird.
Update 1:
Es gibt keine Möglichkeit, kann es über Frühling injiziert werden.Ich habe in den Hibernate-Quellcode gegraben und das Metadaten-Objekt wird nirgendwo in SessionFactory gespeichert (was wir von Spring bekommen). Also, es ist nicht möglich, es zu injizieren. Aber es gibt zwei Möglichkeiten, wenn Sie es im Frühjahr Weg wollen:
- Klassen bestehende erweitern und anpassen den ganzen Weg von
LocalSessionFactoryBean -> MetadataSources -> MetadataBuilder
LocalSessionFactoryBean Dies ist, was Sie in Spring konfigurieren und es hat ein Objekt von MetadataSources. MetadataSources erstellt MetadataBuilder, der wiederum MetadataImplementor erstellt. Alle oben genannten Operationen speichern nichts, sie erstellen nur Objekte im laufenden Betrieb und kehren zurück. Wenn Sie eine Instanz von MetaData haben möchten, sollten Sie die obigen Klassen erweitern und modifizieren, damit sie eine lokale Kopie der entsprechenden Objekte speichern, bevor sie zurückkehren. Auf diese Weise können Sie einen Verweis auf MetadataImplementor haben. Aber ich würde das wirklich nicht empfehlen, es sei denn, es wird wirklich benötigt, weil sich die APIs im Laufe der Zeit ändern könnten.
Auf der anderen Seite, wenn Sie nichts dagegen haben, ein MetaDataImplemetor von Session bauen, wird der folgende Code Ihnen helfen:
EntityManagerFactoryImpl emf=(EntityManagerFactoryImpl)lcemfb.getNativeEntityManagerFactory();
SessionFactoryImpl sf=emf.getSessionFactory();
StandardServiceRegistry serviceRegistry = sf.getSessionFactoryOptions().getServiceRegistry();
MetadataSources metadataSources = new MetadataSources(new BootstrapServiceRegistryBuilder().build());
Metadata metadata = metadataSources.buildMetadata(serviceRegistry);
SchemaUpdate update=new SchemaUpdate(serviceRegistry,metadata); //To create SchemaUpdate
// You can either create SchemaExport from the above details, or you can get the existing one as follows:
try {
Field field = SessionFactoryImpl.class.getDeclaredField("schemaExport");
field.setAccessible(true);
SchemaExport schemaExport = (SchemaExport) field.get(serviceRegistry);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
Verwandte: http://stackoverflow.com/questions/32178041/where-did-configuration-generateschemacreationscript-go-in-hibernate-5 –
Ich finde den persistence.xml-Parser aus diesem Beitrag ziemlich praktisch: http://stackoverflow.com/questions/23310617/how-to-use-schemaexporttool-with-jpa-and-hibernate-4-3 –
Der ServiceRegistry-Fehler, dem Sie gegenüberstanden war aufgrund der Tatsache, dass MetadataSources 'StandardServiceRegistry' erwartet, während die ServiceRegistry von SessionFactoryImpl nicht vom obigen Typ ist. Schauen Sie in meine Antwort für die Details. – James