Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Hibernate SchemaUpdate class with a JPA persistence.xml?

I've a main method using SchemaUpdate to display at the console what tables to alter/create and it works fine in my Hibernate project:

 public static void main(String[] args) throws IOException {
  //first we prepare the configuration
  Properties hibProps = new Properties();
  hibProps.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jbbconfigs.properties"));
  Configuration cfg = new AnnotationConfiguration();
  cfg.configure("/hibernate.cfg.xml").addProperties(hibProps);

  //We create the SchemaUpdate thanks to the configs
  SchemaUpdate schemaUpdate = new SchemaUpdate(cfg);


  //The update is executed in script mode only
  schemaUpdate.execute(true, false);
  ...  

I'd like to reuse this code in a JPA project, having no hibernate.cfg.xml file (and no .properties file), but a persistence.xml file (autodetected in the META-INF directory as specified by the JPA spec).

I tried this too simple adaptation,

Configuration cfg = new AnnotationConfiguration();
cfg.configure();

but it failed with that exception.

Exception in thread "main" org.hibernate.HibernateException: /hibernate.cfg.xml not found

Has anybody done that? Thanks.

like image 444
John Rizzo Avatar asked Apr 15 '10 12:04

John Rizzo


People also ask

What is JTA persistence xml?

The jta-data-source (for JTA-aware data sources) and non-jta-data-source (for non-JTA-aware data sources) elements specify the global JNDI name of the data source to be used by the container. The JAR file or directory whose META-INF directory contains persistence. xml is called the root of the persistence unit.

What is the use of persistence xml in hibernate?

The persistence. xml file must define a persistence-unit with a unique name in the current scoped classloader. The provider attribute specifies the underlying implementation of the JPA EntityManager. In JBoss AS, the default and only supported / recommended JPA provider is Hibernate.

Where do I put persistence xml?

xml should be put in the EJB JAR's META-INF directory. If you package the persistence unit as a set of classes in a WAR file, persistence. xml should be located in the WAR file's WEB-INF/classes/META-INF directory.

What is the role of persistence xml in JPA?

The persistence. xml configuration file is used to configure a given JPA Persistence Unit. The Persistence Unit defines all the metadata required to bootstrap an EntityManagerFactory , like entity mappings, data source, and transaction settings, as well as JPA provider configuration properties.


2 Answers

Kariem is on the right track, but let me attempt to clarify.

Let's assume that you have a vanilla JPA-standard configuration with nothing Hibernate-specific, except for the Hibernate jars on the classpath. If you are running in J2SE bootstrap mode, you already have some code that looks something like this, either in Java or as Spring configuration, etc.:

Map<String, Object> props = getJPAProperties();
EntityManagerFactory emf = 
    Persistence.createEntityManagerFactory("persistence-unit-name", props);

To run SchemaUpdate, simply use this instead:

Map<String, Object> props = getJPAProperties();
Ejb3Configuration conf = 
    new Ejb3Configuration().configure("persistence-unit-name", props);
new SchemaUpdate(conf.getHibernateConfiguration()).execute(true, false);

I'm not sure how this would operate in a container environment, but in a simple J2SE or Spring type of configuration, that's all there is to it.

like image 78
Peter Centgraf Avatar answered Sep 24 '22 03:09

Peter Centgraf


You should use Ejb3Configuration instead of the normal configuration. Refer to the entity manager documentation, at the end of the bootstrapping section in the hibernate documentation.

(copied from above source with minor adaptations)

Ejb3Configuration cfg = new Ejb3Configuration();
EntityManagerFactory emf = 
  cfg.addProperties(properties)                  // add some properties
     .setInterceptor(myInterceptorImpl)          // set an interceptor
     .addAnnotatedClass(MyAnnotatedClass.class)  // add a class to be mapped
     .addClass(NonAnnotatedClass.class)          // add an hbm.xml file using the Hibernate convention
     .addResource("mypath/MyOtherCLass.hbm.xml") // add an hbm.xml file
     .addResource("mypath/orm.xml" )             // add an EJB3 deployment descriptor
     .configure("/mypath/hibernate.cfg.xml")     // add a regular hibernate.cfg.xml
     .buildEntityManagerFactory();               // create the entity manager factory

As you can see, you can mix a lot of different types of configuration.

If it's only for the schema update part, you can just set a property in your persistence.xml: hibernate.hbm2ddl.auto:

<persistence-unit name="app1">
   <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <properties>
     …
     <property name="hibernate.hbm2ddl.auto" value="update"/>
   </properties>
</properties>

See here for a few more references.

like image 41
Kariem Avatar answered Sep 24 '22 03:09

Kariem