JPA Mini Book – First Steps and detailed concepts

What is the persistence.xml file used for? And its configurations?

The persistence.xml file is responsible for several applications configurations; it can hold database, application and JPA implementations specific configurations.

In the persistence.xml code presented here are the EclipseLink configurations, but the concept and the theory applied to the Java classes in this post can be applied to every JPA implementation.

The persistence.xml file must be located in the META-INF folder in the same folder of the Java classes. Below is a picture that shows where the file should be placed:

This picture is valid for Eclipse IDE. For Netbeans it is necessary to check in its documentation where the correct place to put the file is. At this moment I do not have the Netbeans installed in my pc to check it.

If you got the error message: “Could not find any META-INF/persistence.xml file in the classpath” here are some tips that you can check:

  • Open the generated WAR file and check if the persistence.xml is located at “/WEB-INF/classes/META-INF/”. If the file is automatically generated and is not there your error is at the WAR creation, you need to put the persistence.xml file where the IDE expects. If the artifact creation is manually check the creation script (ant, maven).
  • If your project is deployed with EAR file check if the persistence.xml file is in the EJB jar root. If the file is automatically generated and is not there your error is at the WAR creation, you need to put the persistence.xml file where the IDE expects. If the artifact creation is manually check the creation script (ant, maven).
  • If your project is a JSE project (desktop) you should check if the file is not in the folder “META-INF”. As default behavior the JPA will search in the JAR root for the folder and file: “/META-INF/persistence.xml”.
  • Check if the file has the name: “persistence.xml”. The file must have the name with all letters in lowercase.

If the JPA cannot find the file the error above will be displayed. As general rule, it is a good practice to put the file as displayed above.

Check below a sample of persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>

<persistence version="2.0"
	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">

	<persistence-unit name="MyPU" transaction-type="RESOURCE_LOCAL">
		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

		<class>page20.Person</class>
		<class>page20.Cellular</class>
		<class>page20.Call</class>
		<class>page20.Dog</class>

		<exclude-unlisted-classes>true</exclude-unlisted-classes>

		<properties>
			<property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:mem:myDataBase" />
			<property name="javax.persistence.jdbc.user" value="sa" />
			<property name="javax.persistence.jdbc.password" value="" />
			<property name="eclipselink.ddl-generation" value="create-tables" />
			<property name="eclipselink.logging.level" value="FINEST" />
		</properties>
	</persistence-unit>

	<persistence-unit name="PostgresPU" transaction-type="RESOURCE_LOCAL">
		<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>

		<class>page26.Car</class>
		<class>page26.Dog</class>
		<class>page26.Person</class>

		<exclude-unlisted-classes>true</exclude-unlisted-classes>

		<properties>
			<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost/JpaRelationships" />
			<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
			<property name="javax.persistence.jdbc.user" value="postgres" />
			<property name="javax.persistence.jdbc.password" value="postgres" />
			<!-- <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> -->
			<property name="eclipselink.ddl-generation" value="create-tables" />
			<!-- <property name="eclipselink.logging.level" value="FINEST" /> -->
		</properties>
	</persistence-unit>
</persistence>

About the code above:

  • <persistence-unit name=”MyPU” => with this configuration it is possible to define the Persistence Unit name. The Persistence Unit can be understood as the JPA universe of your application. It contains information about all classes, relationships, keys and others configurations all relating the database to your application. It is possible to add more than one Persistence Unit at the same persistence.xml file as displayed in the code above.
  • transaction-type=”RESOURCE_LOCAL” =>Define the transaction type. Two values are allowed here: RESOURCE_LOCAL and JTA. For desktop applications RESOURCE_LOCAL should be use; for web application both values can be used, the correct value depends on the application design.
  • <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> => Defines the JPA implementation provider. The provider is the application JPA implementation. If your application is using Hibernate, the provider value should be “org.hibernate.ejb.HibernatePersistence” and for OpenJPA “org.apache.openjpa.persistence.PersistenceProviderImpl”.
  • <class></class> => Used to declare the Java classes. In a JEE/JSE usually this is not required; e.g. for a Hibernate desktop application there is no need to declare the classes with this tags, but with EclipseLink and OpenJPA requires the presence of the class tag.
  • <exclude-unlisted-classes>true</exclude-unlisted-classes> => this configurations defines that if a class is not listed in the persistence.xml it should not be handled as an entity (we will see more about entity in the next page) in the Persistence Unit. This configuration is very useful for applications with more than one Persistence Units, where an Entity should appear in one database but not in the other.
  • It is possible to comment a code use the tag <!– –>
  • <properties> => It is possible to add specific JPA implementations configurations. Values like driver, password and user it is normal to find it to all implementations; usually these values are written in the persistence.xml file for a RESOUCE_LOCAL application. To JTA applications the datasources are used by the containers. A datasource can be specified with the tags <jta-data-source></jta-data-source><non-jta-data-source></non-jta-data-source>. Some JBoss versions will require that the presence of this configuration even if the connection is local. Two configurations are worth of mentioning:
Configurations Implementation Used for
eclipselink.ddl-generation EclipseLink Will activate the automatically database table creation, or just validate the database schema against the JPA configuration.
hibernate.hbm2ddl.auto Hibernate
openjpa.jdbc.SynchronizeMappings OpenJPA
eclipselink.logging.level EclipseLink Will define the LOG level of the JPA implementation.
org.hibernate.SQL.level=FINEST org.hibernate.type.level=FINEST Hibernate
openjpa.Log OpenJPA
On the internet you will find the allowed values to each implementation.

50 thoughts on “JPA Mini Book – First Steps and detailed concepts

  1. I copied and pasted and generated a PDF file – let me know how to send it to you – so that you can upload
    Thanks for the wonderful information and sharing your knowledge

  2. Olá. Há realmente necessidade de colocar @IdClass na Entidade?

    Usando apenas 3 @Id aqui na minha Entidade, o hibernate criou sozinho a chave composta. Qual seria o problema recorrente de fazer isso em uma @IdClass?

    • Davi, boa tarde.

      Infelizmente não sei falar se pode haver algum problema em sua abordagem.

      Nos dois livros que li que abordavam sobre JPA ambos falavam para utilizar o IdClass.

      Obrigado pela visita.

  3. Cara, como que faço pra salvar a entidade que tem N-N com atributos? Tudo quanto é coisa que eu faço da erro de detached…

    Eis minha ultima tentativa:

    public String editar(){
    prospecto = prospectoService.buscarProspectoComAcoes(prospecto.getId());

    log.debug(“Antes: “+prospecto.getProspectoCampos().size());

    List prospectoCampos = new ArrayList();

    for(ProspectoHelper hp : ProspectoHelper.extrairDadoDoModelo(dynaFormModelUniao)){
    ProspectoCampo pc = new ProspectoCampo();
    pc.setCampo(campoService.findOne(hp.getPropertyFilter().getCampo().getId()));
    pc.setValor(hp.getPropertyFilter().getValue().toString());
    pc.setProspecto(prospecto);
    prospectoCampos.add(pc);
    }

    prospecto.setProspectoCampos(prospectoCampos);

    log.debug(“Depois: “+prospecto.getProspectoCampos().size());

    prospecto.adicionarAcao(acaoSelecionada);

    try{
    prospectoService.save(prospecto);
    }catch(Exception e){
    log.error(“Erro ao editar Prospecto!”, e);
    messageUtil.sendErrorMessageToUser(“global.error”, “global.insert.error”, e.getMessage());
    return null;
    }

    return getRadarPath();
    }

    Abraços

    • Marco, boa tarde.

      Repare que você não tem uma transação única, por isso que ao buscar o objeto de um serviço e salvar em outro ele apresenta essa mensagem.

      Leia a parte sobre esse erro aqui deste post, ele explica direitinho o que está acontecendo.

      Obrigado pela visita.

  4. i am a self-study for java.
    I have view Your tutorials that are very very simple to understand.,
    I have a request for you.

    From the mini book for JPA and the tutorial for JSF , i have noted that into the Entity class and the managedbeans with scoped Session that implements Serializable you put a field :private static final long serialVersionUID = 343L;

    Whi into all class that implements Serializable have a field static final of type Long?
    private static final long serialVersionUID = 343L;
    or
    private static final long serialVersionUID = 1L

    ??????????????

    whi it is static final long ?
    please explique me ……..

    tank you
    Mauro

  5. Thanks for taking the time to write out this tutorial.

    A few suggestions to improve this article.
    – Firstly its a good practice to make sure all entity classes implement the java.io.Serializable interface.

    – When setting the @OneToMany annotation, it is important to talk about the CascadeType options for easier creation/updation of entities. An example of code for insert/update/delete of the entities with and without the CascadeType option will demonstrate the difference in use.

    – The mappedBy value in the cellular class = cellular. What this defines should be explained. This actually refers to the instance variable cellular on the Call object. Since the names are all kept the same most readers will be confused on the name mapping. They may think it refers to the classname when in fact it has nothing to do with the class name.
    I find it useful to actually change the names to demonstrate the actual relationships. So calling cellular, cellularRef on the Call object would make this point more obvious.

    • Hello Kapil,

      1) I just see implementing java.io.Serializable as good practice if you have a multi clustered environment or remove EJB (or anything related to serialization). Do you have any article that talk about that always implementing java.io.Serializable is a good practive?
      2) In this article there is a page that talks about Cascade. [=
      3) Thanks for the mappedBy tip. I will edit it later. [=

      Thanks for passing by! =D

      • When you write code you do not know the target configuration for deployment especially for packaged apps. If you do not implement Serializable and ship your bundle off to a client and they are running a multi clustered environment, guess what will happen?

        • Hello Kapil,

          I do know some seniors Java developers that use JPA and never needed to work with clustered environments.

          Thinking about OO, if a class will never be used in an clustered environment why would it be considered a good practice to add this Interface?

          You thoughts will remain here to be used as an alert to other developers.

          Thanks for passing by! [=

          • Well its good to have differences in opinion :).

            When I write software I can never tell if it is going to be used in a clustered environment or not. All the enterprises i have worked for have had nothing but multi clustered (Cluster of clusters) environments. I rarely write software that would work only on a single node. Unless of course its a quick Proof Of concept.

          • Indeed.

            I always will have the idea that a code that does not follow a good practice will run in every environment.

            In your case, is not good practice but a requirement. Where I live I know a lot of developers that never worked with clustered environment.

            Thanks for passing by.

  6. I outlined the reason why you would implement the interface in my previous comment.
    I can try and explain once again.
    As an example let’s say you are building a Human Resources application that you intend to sell to clients. You are using JPA and do not implement the Serializable interface. One of the clients you sell to is a very large corporation that has a clustered environment. When they buy your application and try to deploy it on their environment it will start throwing serialization errors.
    Does that make sense?

    • Hello Kapil,

      I do not know what is reality of software programming where you live, but I know several developers that never built a software to be sold.

      A developer must understand this: If your software is to be used in a non clustered environment, you will not need to add the interface. If your software is for a clustered environment the interface is not a good practice, but a requirement. That is the difference.

      And if you are building a software to be sold, only by applying the interface will not make your software ready for a clustered environment. A clustered environment is a Requirement that should be specified in the beginning.

      I do respect your opinion, but I do not agree with it. [=

      Thanks for passing by.

  7. Couple of points of interest here :

    1. Usually have the owner of the ManyToMany relationship be the entity that has the less rows when navigating the right side of the join.
    So for e.g. If 1 student can have many courses and many students can have one course we have a many to many relationship between students and courses. In such a model (practically), when navigating from a student record to courses you will have fewer records than from navigating courses to student. In such a case, it makes more sense to define the owner of the relationship be student and not courses. The reason I am saying this when you have a new student in the system its more optimal from a SQL standpoint to navigate from Student to Courses and add the new course. If you had to navigate the other way you will potentially have many more records which means more objects loaded to represent the relationship which means a poorer performing application.

    2. Also in your example you do not need to set both of these
    person.setDog(dogs);
    dog.setPersons(persons);

    just person.setDog(dogs) should work.

    • Hello Kapil,

      1. Sometimes you do not know which entity will have less rows, that I think that the books that I read do not put who should be the owner like you did. But I did like your point of view.

      2. To work like that depends on your implementation. The JPA Pro 2 book makes it clear that passing to only one side the reference the other side will see it.

      Thanks for passing by.

      PS.: Sorry for taking too long to answer you.

    • I do not forgot it, but sometimes an implementation does. =P

      Take the JPA implementation by example, you can have some methods behaving different in each implementation.

      Sometimes The spec says only what a method can or cannot do, allowing it to behave and to have an final destination chosen by it own.

      Thanks for passing by.

  8. Yes and this is perfectly acceptable. You change behavior at deployment time w/o having to recompile code.
    However adding an interface to the codebase will require a recompile. See the difference?
    My point is it does not hurt to put in the interface. It costs nothing but makes your app scale up in a J2EE deployment. Even scaling vertically where the Views & Controller runs in one JVM (Servlets/JSP’s) and the Model (Entities) run in another JVM you will not be able to pass entities to the controller because they do not serialize.

    • 1) If you think by OO, a class have no reason to know a Interface that it will not use it.
      2) A team with developers without experience will not know why the serializable is there (I saw that happing a lot of times), and will start adding it to several other classes thinking that it will solve some error.

      I sorry, but no, I do not see it as good practice. If it is not a requirement, it should not be present.

  9. Hi,
    I have the below scenario. Can I map this relationship in JPA xml if so can you please tell me how to do. Thank you so much.
    We have tables users (userId), organizations(orgId), roles(roleId) and joining tables are users_orgrole_map (userId, orgRoleId) and org_roles_map (orgRoleId, OrgId, roleId). The User Object will have Set of Organizations and Organization Object have set of Roles. (ie User can have different roles in different Organization. UserA belong to OrgA with RoleA permission and UserA belong to OrgB with RoleB permission.)

    • Hello Harishyam,

      Check in this post the page “ManyToMany with extra fields”.

      Thanks for passing by, I am sorry for the late reply. I was very busy this last month.

  10. Hi~ thanks for the great tutorial. It’s very helpful for beginners to understand how composite PK works. I have a question though. How can I create query using only one of the key.

    For instance, I want to find out the cars of a particular CarID.brand. How does it work for your example code? thanks.

    • Hello Dean, how are you?

      You could create the PK key for the query e pass only the value. Something like:
      MyKey key = new MyKey();
      key.setValueA(onlyValueYouHave);
      // do the query

      Thanks for passing by.

  11. Hi, how can i in the example above get all the persons for specific dogId or vice versa using entity manager? thanks

  12. Hi,

    Great post!!
    Could you add the column “cellular_id” to the table “Person”? This makes it clearer. Otherwise, I was scrathcing my head where “cellular_id” is.

    Thanks!

  13. Hello uaihebert,

    Thank you for explaining @TableGenerator. I am a bit confused by how to use initialValue. If I specify an initialValue that is already in use, will the application attempt to overwrite entities in the database? If so, how can I develop an application without having to repeatedly update initialValue when I redeploy the application?

    For example, (1) I deploy the application, and I persist some entities using the web application, (2) I undeploy the application and modify its source code, and (3) I redeploy the application to test my changes. If I don’t update initialValue between steps 1 and 3, will I overwrite entities or otherwise get errors?

    (I will test this myself when I have time, but if you have time I would appreciate your explanation of this.)

    • Hello David, how are you?

      That is a very good question and I do not know the answer without a test too. =/

      Thanks for passing by

Leave a Comment