Je voudrais ajouter sur la réponse de Aviad pour le rendre complet selon la demande OP .
Les internes:
Afin d'obtenir une instance de MetadataImplementor, la solution de contournement consiste à enregistrer une instance de SessionFactoryBuilderFactory par installation Java ServiceLoader. La méthode getSessionFactoryBuilder de ce service enregistré est ensuite appelée par MetadataImplementor avec une instance de lui-même, lorsque hibernate est amorcée. Les références de code sont ci-dessous:
- Service Loading
- Invocation of getSessionFactoryBuilder
Alors, en fin de compte pour obtenir une instance de MetadataImplementor, vous devez mettre en œuvre SessionFactoryBuilderFactory et vous inscrire si ServiceLoader peut reconnaître ce service:
Une implémentation de 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;
}
}
Pour vous inscrire ci-dessus, créez simple fichier texte dans le chemin suivant (en supposant qu'il est un projet Maven, nous avons besoin en fin de compte le dossier « META-INF » soit disponible dans le classpath):
src/main/resources/META-INF/services/org.hibernate.boot.spi.SessionFactoryBuilderFactory
Et le contenu du fichier texte doit être une seule ligne (peut même être plusieurs lignes si vous avez besoin d'enregistrer plusieurs instances) indiquant le chemin de classe complet de votre implémentation de SessionFactoryBuilderFactory. Par exemple, pour la classe ci-dessus, si le nom de votre package est "com.yourcompany.prj", le contenu du fichier doit être le suivant.
com.yourcompany.prj.MetadataProvider
Et c'est, si vous exécutez votre application, l'application de printemps ou mise en veille prolongée autonome, vous aurez une instance de MetadataImplementor disponible par le biais d'une méthode statique mise en veille prolongée est une fois bootstraped.
Mise à jour 1:
Il n'y a aucun moyen peut être injecté par ressort.J'ai creusé dans le code source de Hibernate et l'objet de métadonnées n'est stocké nulle part dans SessionFactory (ce que nous obtenons de Spring). Donc, il n'est pas possible de l'injecter. Mais il y a deux options si vous le voulez sur le chemin de printemps:
- étendre les classes existantes et personnaliser tout le chemin de
LocalSessionFactoryBean -> MetadataSources -> MetadataBuilder
LocalSessionFactoryBean est ce que vous configurez dans Spring et il a un objet de MetadataSources. MetadataSources crée MetadataBuilder qui à son tour crée MetadataImplementor. Toutes les opérations ci-dessus ne stockent rien, elles créent juste l'objet à la volée et retournent. Si vous souhaitez avoir une instance de MetaData, vous devez étendre et modifier les classes ci-dessus afin qu'elles stockent une copie locale des objets respectifs avant leur retour. De cette façon, vous pouvez avoir une référence à MetadataImplementor. Mais je ne recommanderais pas vraiment ceci à moins que ce soit vraiment nécessaire, parce que les API pourraient changer avec le temps.
D'autre part, si vous ne me dérange pas la construction d'un MetaDataImplemetor de SessionFactory, le code suivant vous aidera:
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();
}
connexes: http://stackoverflow.com/questions/32178041/where-did-configuration-generateschemacreationscript-go-in-hibernate-5 –
Je trouve le parseur persistence.xml de ce post assez pratique: http://stackoverflow.com/questions/23310617/how-to-use-schemaexporttool-with-jpa-and-hibernate-4-3 –
L'erreur ServiceRegistry que vous avez rencontrée était dû au fait que MetadataSources s'attend à 'StandardServiceRegistry' alors que le serviceRegistry de SessionFactoryImpl n'est pas du type ci-dessus. Regardez dans ma réponse pour les détails. – James