Search This Blog

Tuesday 19 March 2013

persistence.xml

In previous post we have seen the persistence.xml file - the file provides all the configuration information needed to get JPA up and running. We also saw that the JPA standard is very particular of the location of the file.
In our previous example we had both the persistence.xml file and the hibernate.cfg.xml file. We did not add any configuration information in the persistence.xml file, choosing instead to redirect to the hibernate configuration file.
This step is not necessary. We can have all the configuration information in a single file:
<?xml version="1.0" encoding="UTF-8"?>
<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_1_0.xsd"
    version="1.0">
    <persistence-unit name="firstOne">
        <class>com.basic.Owner</class>
        <class>com.basic.Pet</class>
        <properties>
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
            <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/pets"/>
            <property name="hibernate.connection.username" value="postgres"/>
            <property name="hibernate.connection.password" value="root"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create" />

        </properties>
    </persistence-unit>
</persistence>
As can be seen the file now includes all the properties needed for Hibernate's JPA implementation to work.
The root element is the persistence element. It includes the xml schema definition for JPA. I found it within the hibernate-entitymanager.jar
Within the persistence element is the persistence-unit element. Every persistence-unit holds configuration information needed to run a single EntityManagerFactory. So if your project requires you to connect to multiple databases, then you add multiple such persistence-units in the <persistence> element. Every persistence-unit requires a name so as to distinguish them from other such persistence units.
Within the persistence-unit element we have the class element. Here I have listed the annotated classes to use as entities.
JPA states that the annotated classes will be auto-discovered in an Enterprise environment, but in a Standalone environment we need to specify the entities using the <class> element. The Hibernate team has gone  a step ahead and provided support for auto detection of classes in the Standalone application too. So I can go ahead and remove the class element. The code should work fine as Hibernate will automatically scan packages and locate my entity classes.
Similar to the class element we have the mapping-file element for xml based entity mappings. If our entities reside in a jar then we can specify the jar name using the jar-file element.
I commented my <class> entries and executed the code:
906  [main] DEBUG org.hibernate.ejb.Ejb3Configuration  - PersistenceMetadata [
    name: firstOne
    jtaDataSource: null
    nonJtaDataSource: null
    transactionType: RESOURCE_LOCAL
    provider: null
    classes[
    ]
    packages[
    ]
    mappingFiles[
    ]
    jarFiles[
    ]
    hbmfiles: 0
    properties[
        hibernate.connection.username: postgres
        hibernate.connection.password: root
        hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
        hibernate.show_sql: true
        hibernate.connection.url: jdbc:postgresql://localhost:5432/pets
        hibernate.connection.driver_class: org.postgresql.Driver
        hibernate.hbm2ddl.auto: create
    ]]
...
1187 [main] DEBUG org.hibernate.ejb.Ejb3Configuration  - Detect class: true; det
ect hbm: true
As seen Hibernate is auto set to detect class (and hbm files). If we retain the class elements then, the logs would vary for the below statement:
classes[
        com.basic.Owner        com.basic.Pet    ]
    packages[
    ]
We can control what Hibernate tries to auto-detect:
<property name="hibernate.archive.autodetection" value="class,hbm" />
This property tells Hibernate what to scan for. If the value is an empty quotes, Hibernate will not scan for hbm or classes.( I felt the check could be added much higher in the Hibernate source code)
Even if an entity is present but the scan option is off then the particular entity will be ignored unless it is specified within the class element.
This provides us with an optimization opportunity. If we need to speed up application start-up we can simply list all our entities and  switch off the scanning.
The next is the properties element. This element holds a collection of property elements. The property elements are used to provided information in name value pairs. The names used here are provider specific. In our case all the hibernate configuration needed, has been added here.
There is one other element - provider.
<provider> org.hibernate.ejb.HibernatePersistence</provider>
This is useful when working with multiple persistence providers.
(I was also thinking if this could be used to speed up the start up code. In an earlier post we saw how Persistence class searches through the java files looking for the persistence provider. Ideally if this value is set, then the search could be avoided, especially in a single provider environment.) There are some more settings available, but more on those later.

No comments:

Post a Comment