Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the Hibernate Configuration after the EntityManagerFactory has been built?

My web framework (Play 1.2.5) creates an EJB3Configuration local to a method which it uses to create an EntityManagerFactory (source). I am working on a script and would like to run the generateSchemaUpdateScript() method from Configuration to make SQL scripts I can verify and run on production deploys. The problem I am having is that I cannot figure out how to access the Configuration object that was used or how to generate a Configuration object after the EntityManagerFactory has been built.

like image 280
Ransom Briggs Avatar asked Sep 07 '12 14:09

Ransom Briggs


People also ask

What is Hibernate EntityManagerFactory?

EntityManager. The EntityManager API is used to access a database in a particular unit of work. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. This interface is similar to the Session in Hibernate. Persistence context.

What is Hibernate SessionFactory and how do you configure it?

Most importantly, the SessionFactory in Hibernate is responsible for the creation of Session objects. The Hibernate Session provides methods such as save, delete and update, all of which are used to perform CRUD-based operations on the database to which the SessionFactory connects.

What is Hibernate configuration object?

The Configuration object is the first Hibernate object you create in any Hibernate application. It is usually created only once during application initialization. It represents a configuration or properties file required by the Hibernate.


2 Answers

You cannot get the configuration object back from the entitymanagerfactory because hibernate implementation EntityManagerFactoryImpl does not hold a reference to the configuration object

Your choices are

  • duplicates the code from JPAPlugin in your script to create your own configuration object
  • configure hibernate tools to work on your classes. I never used this tool myself but I guess that properly configured he can generate the ddl for you
  • generates back the ddl script from your database
like image 176
Seb Cesbron Avatar answered Sep 18 '22 00:09

Seb Cesbron


Once the Entity manager factory has been created you are not supposed to have the handle to the Configuration object, partly because of the design that Configuration is supposed to exhibit immutable behavior in that you cannot change its properties.

I'm referring to Hibernate 3.6.8 source and the EJB3Configuration class has method

public AnnotationConfiguration getHibernateConfiguration() {
        //TODO make it really read only (maybe through proxying)
        return cfg;
    }

AnnotationConfiguration is declared as deprecated as all of its functionality is moved to Configuration class.

So I think that using this you can get the handle to your configuration once it's been created. You have to be very careful though not to change anything in that configuration.

This is explained in the javadocs here

After #buildEntityManagerFactory() has been called, you no longer can change the configuration state (no class adding, no property change etc)

Having said that, what you are trying to achieve to do is something which is STRICTLY NOT ADVISED especially on production database. See here

Hibernate has a property named “hibernate.hbm2ddl.auto” which is to assist the schema auto generation in case of evolving scripts. What you are trying to achieve programmatically has same effect as giving it a value of update like below in your persistence xml. In fact under the covers, the method generateSchemaUpdateScript is called by the configuration when you have the value of "hibernate.hbm2ddl.auto" set to "update"

<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_2_0.xsd"
             version="2.0">
   <persistence-unit name="xyz" transaction-type="RESOURCE_LOCAL">
        <properties>
            ....................
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            ......................
        </properties>
    </persistence-unit>
</persistence>

You can refer to other possible values for this attribute here

However the Hibernate docs stricltly advises against using this against production database.

The definitive book on Hibernate "Java persistence with Hibernate" cautions this

WARNING We’ve seen Hibernate users trying to use SchemaUpdate to update the schema of a production database automatically. This can quickly end in disaster and won’t be allowed by your DBA.

and also few limitations about the update schema process

An additional option for this configuration property, update, can be useful during development: it enables the built-in SchemaUpdate tool, which can make schema evolution easier. If enabled, Hibernate reads the JDBC database metadata on startup and creates new tables and constraints by comparing the old schema with the current mapping metadata. Note that this functionality depends on the quality of the metadata provided by the JDBC driver, an area in which many drivers are lacking. In practice, this feature is therefore less exciting and useful than it sounds.

UPDATE 1 : If you don’t have access to EJB3Configuration and your ultimate aim is to create the update schema scripts for JPA annotated entities then you can programmatically create the EJB3Configuration in a java main class using a persistence xml file which contains the configuration details of your database and run the schema export tool . See this example how you can do it. So this way you could run the tool on JPA entities outside of your framework or even container.

UPDATE 2

The example code listed here shows how you could use Hibernate schema update when creating database migrations for play applications. Seems like this is what you wanted !

like image 32
Shailendra Avatar answered Sep 22 '22 00:09

Shailendra