GlassFish Project - Java Persistence API - Frequently Asked Questions 

Table of Contents

A. XML and Packaging

  1. What does the simplest persistence.xml look like on the Java EE platform?

  2. How does my persistence.xml file vary between the Java EE and the Java SE environments?

  3. I am getting an XML validation error “Cannot find the declaration of element 'persistence'”. What could be going wrong?

  4. Is there a standard name for the XML mapping file?

  5. Can I name my XML mapping file as anything other than META-INF/orm.xml?

  6. I am writing a simple web application that uses the Java Persistence API. How should I package my entity classes?

  7. I am writing an enterprise application (ear) that uses the Java Persistence API. How can I package my persistence classes?

  8. Can I use the Java Persistence API in a Java EE client application?

  9. I have an ear file which has an ejb-jar file and a war file. The ejb-jar defines a persistence unit. Can my web module use that persistence unit?

  10. Can I share a persistence context across multiple applications?

  11. Can I share a persistence context among multiple modules in an application (ear)?

  12. How should I package my persistence classes so that I can share the persistence context among different modules in the application?

  13. I am getting “java.lang.IllegalArgumentException: Invalid ejb jar my-ejb.jar...”

B. O/R Mapping and Annotation

  1. How do I specify the default values for schema or catalog names for my persistence unit?

  2. I am trying to persist a generic class, but MetaDataHelper.getReturnTypeFromGeneric() throws an exception.

  3. I am getting an Exception that says “Exception Description: Multiple writable mappings exist for the field ...”

  4. I am using @Id in my entity class, yet I am getting a TopLink exception: “Exception Description: Entity class [class xxx] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass.”

  5. I have a relationship set up between my entities. When I set one side of the relationship, the change is not reflected in other side. This used to work in CMP 2.x. What has changed?

  6. When I am accessing my entities, I get a database exception because incorrect column names are used by TopLink Essentials.

  7. Can I have my entity data spread across multiple tables?

  8. Can I use a non-primary key type column as an Id (@Id) field in my entity?

  9. I am not able to locate javax.persistence.AccessType.class. How do I specify access-type for my entity class?

  10. Can I use a NamedQuery annotation to annotate an embeddable class or MappedSuperclass?

  11. How do I specify access-type in my entity class?

  12. Is it possible to mix access-types in an inheritance hierarchy?

  13. Is it possible for an embeddable class to have a different access-type than the entity class that embeds that type?

  14. Should I make my entity Serializable?

  15. What's the difference between @IdClass and @EmbeddedId?

C. Automatic Table Generation (Java2DB)

  1. Is there a way to generate tables and columns for my persistence application?

  2. I am using Java2DB in my application, does it make my application non-portable?

  3. How do I generate the tables with some specific columns being indexed?

  4. Does Java2DB generate constraints in the database?

D. Dependency Injection, JNDI lookup, EntityManager

  1. I am getting a NullPointerException in my web application while trying to use the injected EntityManager. What is the problem?

  2. How should I get hold of an EntityManager in my Servlet?

  3. Can I use javax.persistence.Persistence.createEntityManagerFactory() to get hold of an EntityManagerFactory in my web application?

  4. Can I use a resource-local EntityManager in my web application?

  5. I am calling merge, yet the entity state is detached. What am I doing wrong?

  6. I have called em.merge(e) and yet I am getting an IllegalArgumentException while trying to delete an entity from the database using em.remove(e). What am I doing wrong?

  7. EntityManager.persist() throws TransactionRequiredException in a servlet. What am I doing wrong?

E. Miscellaneous questions

  1. I am getting a java.security.PrivilegedActionException : Error opening socket to server localhost on port 1527 message : nullError Code: 0. What am I doing wrong?

  2. What is the purpose of -javaagent option? What happens if I don't use it?

  3. How can I configure the cache used by TopLink Essentials?

  4. How do I configure the logging level for Toplink Essentials?

  5. How can I see the sql generated by Toplink Essentials?

  6. How can I control the connection pool settings for an entity manager in a Java SE environment?

Answers

XML and Packaging related questions

Q. What does the simplest persistence.xml look like on the Java EE platform?

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

<persistence-unit name="xxx"/>

</persistence>


Q. How does my persistence.xml file vary between the Java EE and the Java SE environments?

In the Java SE, datasource is not supported, so you have to specify database properties using <properties> as shown below. Moreover, there are a few important ways persistence.xml varies between the Java EE and the Java SE environments: e.g. you have to specify provider name using the <provider> element, list all managed classes using the <class> element and only RESOURCE_LOCAL transaction type is supported. In Java SE, a typical persistence.xml file looks like this:

<persistence xmlns=”http://java.sun.com/xml/ns/persistence” version=”1.0”>

<persistence-unit name="xxx" transaction-type="RESOURCE_LOCAL">

<provider>oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider</provider>
<class>entity1</class>
<class>entity2</class>
<properties>

<property name="toplink.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver"/>
<property name="toplink.jdbc.url" value="jdbc:derby://localhost:1527/sun-appserv-samples"/>
<property name="toplink.jdbc.user" value="APP"/>
<property name="toplink.jdbc.password" value="APP"/>

</properties>

</persistence-unit>

</persistence>


Q. I am getting an XML validation error “Cannot find the declaration of element 'persistence'”. What could be going wrong?

It is likely that you are you not using the namespace or using an incorrect namespace in your persistence.xml file. You must use namespace and supply the correct value for it as shown below:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">

<persistence-unit ...

</persistence>


Refer to issue #579 for more discussion on this issue.

Q. Is there a standard name for the XML mapping file?

Yes, there is a default name for this file. It is called META-INF/orm.xml. But, this file need not always be called META-INF/orm.xml file. You can give any name you like (see next question), but there is a definite advantage if you use the default name and location. That way you don't have to specify the name in persistence.xml file. Just package the XML mapping file in your jar as META-INF/orm.xml. Refer to section #6.2.1.6 of the spec for more details.

Q. Can I name my XML mapping file as anything other than META-INF/orm.xml?

Yes, you can name it anything you like. Remember that, if the mapping file is packaged as META-INF/orm.xml, then you don't have to do anything special. Otherwise, you should use <mapping-file> element in the persistence.xml file. Please also note that the name you specify using mapping-file element is not relative to the persistence.xml. Instead, at runtime it is used in a call like ClassLoader#findResourceByName() .
e.g. If you have packaged your jar file to look like this:

ejb.jar/

META-INF/persistence.xml

   /mappings.xml


then, the mapping-file element should look like this:

<mapping-file>META-INF/mappings.xml</mapping-file>


Q. I am writing a simple web application that uses the Java Persistence API. How should I package my entity classes?

There are several ways to package your entity classes:

a) package all the entity classes along with META-INF/persistence.xml in a jar file, say 'entities.jar', and put it in WEB-INF/lib as shown below:

foo.war/

WEB-INF/lib/entities.jar


where entities.jar look like this:

entities.jar/

META-INF/persistence.xml
pkg/Entity1.class
pkg/Entity2.class


b) package all the entity classes along with META-INF/persistence.xml in WEB-INF/classes as shown below:

foo.war/

WEB-INF/classes/
META-INF/persistence.xml
pkg/Entity1.class
pkg/Entity2.class


For more information on this, refer to Introduction to using Java Persistence API in a web application in Java EE environment.

Q. I am writing an enterprise application (ear) that uses the Java Persistence API. How can I package my persistence classes?

There are several ways to package your persistence classes. We recommend the following structure for your ear file:

a.ear/

ejb.jar
foo.war
lib/my-pu.jar

 

For more details, refer to Using Java Persistence API in Java EE Platform - Part II

Q. Can I use the Java Persistence API in a Java EE client application?

Yes. See Using Java Persistence API in application client in Java EE platform

Q. I have an ear file which has an ejb-jar file and a war file. The ejb-jar defines a persistence unit. Can my web module use that persistence unit?

No. When a persistence unit is packaged inside a module like ejb-jar or war, it is private to that module. For a persistence unit to be visible to all modules, it needs to be packaged in a library jar file in the ear file. We recommend you use ear/lib directory for this purpose. e.g.

a.ear/

ejb.jar
foo.war
lib/my-pu.jar


Q. Can I share a persistence context among multiple applications?

No, this is not possible because each application uses a different classloader in the same JVM.

Q. Can I share a persistence context among multiple modules in an application (ear)?

Yes it is possible to share the persistence context among multiple modules in an application when the modules use local calling semantics, e.g. Servlet -> local EJB -> local EJB or EJB1 -> EJB2. Note that, you can't share the persistence context across remote EJB calls.

Q. How should I package my persistence classes so that I can share the persistence context among different modules in the application?

You must use an ear-scoped persistence unit, i.e. you must package persistence entity classes in a library jar file.

Q. I am getting “java.lang.IllegalArgumentException: Invalid ejb jar my-ejb.jar: it contains zero ejb. A valid ejb jar requires at least one session/entity/message driven bean” although my jar file contains some @Entity annotated classes. What am I doing wrong?

It is very likely that you have packaged only entity (@Entity) classes in that jar file and you have designated that jar file as an EJB module either by having an empty ejb-jar.xml inside it or by specifying <module>ejb</module> in application.xml. In EJB 3.0, an @Entity annotated class is no longer an EJB because it can be used outside the EJB container. So, don't specify that jar file as an ejb-jar. For further details, refer to this forum discussion: http://forums.java.net/jive/thread.jspa?forumID=56&threadID=16319

O/R Mapping and annotation related questions

Q. How do I specify the default values for schema or catalog names for my persistence unit?

You can use an XML mapping file to specify default values for information that applies to the entire persistence unit, e.g. schema/catalog name, access-type etc. e.g. to specify the schema name for the entire persistence unit, provide an orm.xml that looks like this:

<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" version="1.0">
    <persistence-unit-metadata>
        <persistence-unit-defaults>
            <schema>TestSchema</schema>
        </persistence-unit-defaults>
    </persistence-unit-metadata>
</entity-mappings>

Look at issue #580 for a discussion on this issue.

Q. I am trying to persist a generic class, but MetaDataHelper.getReturnTypeFromGeneric() throws an exception. My entity looks like this:
@Entity
public class Foo<T extends Bar> extends FooBar {
private List<T> myVar = new ArrayList<T>();
...
}

This is not allowed. Refer to http://forums.java.net/jive/thread.jspa?threadID=14190 for more discussion on this.
 
Q. I am getting an exception from TopLink that says “Exception Description: Multiple writable mappings exist for the field ...”

This happens when you are trying to map multiple entity fields or properties to the same column in the database. Annotate all but one of them as read-only by using updatable=false,insertable=false. This can be used both for @Column as well as @JoinColumn annotations. Refer to http://forums.java.net/jive/thread.jspa?threadID=14559 for a complete example that shows how to use this feature.

Q. I am using @Id in my entity class, yet I am getting a TopLink exception: “Exception Description: Entity class [class xxx] has no primary key specified. It should define either an @Id, @EmbeddedId or an @IdClass.”

It is very likely that you are using mixed access-type in your entity hierarchy. i.e. both fields and properties are annotated in your entity class hierarchy. Fix it to use a single access type. Refer to http://glassfish.java.net/issues/show_bug.cgi?id=353 for further information.

Q. I have a relationship set up between my entities. When I set one side of the relationship, the change is not reflected in other side. This used to work in CMP 2.x. What has changed?

Relationship management has changed in the Java Persistence API spec. In section #3.2.3, the spec says the following:
“Bidirectional relationships between managed entities will be persisted based on references held by the
owning side of the relationship. It is the developer’s responsibility to keep the in-memory references
held on the owning side and those held on the inverse side consistent with each other when they change.
Developers may choose whether or not to update references
held by the inverse side when the owning side changes, depending on whether the application can handle out-of-date references on the inverse side until the next database refresh occurs.”
This means you have to maintain relationships just like you do in your Java programs: if you want both sides of your relationship to be updated, then you have to do it in your program itself. Refer to this forum topic:
http://forums.java.net/jive/thread.jspa?threadID=2657

Q. When I am accessing my entities, I get a database exception because incorrect column names are used by TopLink Essentials.

This typically happens when a user does not specify column names, either using annotations like @Column or @JoinColumn, or using orm.xml file. In such cases, TopLink computes column names based on rules defined in the spec. If the actual database schema differs from the names TopLink comes up with, you shall see such exceptions. To fix this, either you have to change your database schema or specify columns names in your application. Currently, there is no provision in TopLink Essentials to validate the expected schema against the actual database schema. So, you can discover such issues only by testing.

Q. Can I have my entity data spread across multiple tables?

Yes, for every entity, there must be a primary table designated using @Table and zero or more secondary tables designated using @SecondaryTable.

Q. Can I use a non-primary key type column as an Id (@Id) field in my entity?

Yes, you can designate any column of the primary table as an Id field in your entity, but make sure that there are no duplicate entries for that column. We suggest you have a unique constraint for such a column.

Q. I am not able to locate javax.persistence.AccessType.class. How do I specify access-type for my entity class?

In the early draft release of the Java Persistence API spec, this class was there. Later on, the spec was changed. The user no longer has to use this class. A persistence provider automatically figures out if your bean is annotating fields or methods by looking at the class definition. See the latest Entity.java file:

http://glassfish.java.net/source/browse/glassfish/persistence-api/src/java/javax/persistence/Entity.java?rev=HEAD&view=auto&content-type=text/vnd.viewcvs-markup

So it is sufficient to say the following:


@Entity
public class Person {

@Id private String ssn;

}

or

@Entity public class Person {

private String ssn;

@Id public String getId(){return id;}

public void setId(String id) {this.id = id;}

}

Of course it is an error if you annotate both fields and methods at the same time.

Q. Can I use a NamedQuery annotation to annotate an embeddable class or MappedSuperclass?

No, it can only be used for entity classes.

Q. How do I specify access-type in my entity class?

When you use annotations in your entity class, access-type is implicit, i.e. placement of O/R annotations in field or property accessor method automatically determines the access-type for your class. When you are using a mapping XML file, access-type can be specified using <access> element. It is an error to mix access-types in an inheritance hierarchy.

Q. Is it possible to mix access-types in an inheritance hierarchy?

No, all classes in an inheritance hierarchy must use the same access-type. See question above as well.

Q. Is it possible for an embeddable class to have a different access-type than the entity class that embeds that type?

No, you must use the same access-type for the embeddable as you do in the entity class where you use the embeddable class. As a side effect, you can't use the embeddable class in different entity classes with conflicting access-types.

Q. Should I make my entity Serializable?

Yes, you should. Although it is not necessary, it is never-the-less a good practice to make your entity class Serializable so that it is ready to be used in a remote invocation. Otherwise you can't return an entity in a remote business interface of an EJB.

Q. What's the difference between @IdClass and @EmbeddedId?

There is not much difference. Refer to http://forums.java.net/jive/thread.jspa?threadID=17026 where this is discussed.

Automatic Table Generation (Java2DB) related questions

Q. Is there a way to generate tables and columns for my persistence application?

Yes, the Java Persistence API spec defines an API for users to specify database schema information that a provider can use to define the schema in a database. In GlassFish, this feature is known as Java2DB. Refer to the following link for more information: http://blogs.sun.com/roller/page/java2dbInGlassFish

Q. I am using Java2DB in my application, does it make my application non-portable?

Theoretically, yes, because although the  Java Persistence API spec defines API for users to specify database schema information that a provider can use to define the schema in a database, this is an optional feature and is not required to be supported by every compliant persistence provider. But practically speaking, the answer is no because most popular persistence providers support this. Moreover, your mapping specification is totally portable; it's only the generation of DDL feature which may not be available in all providers. Since this is usually used in development environment, we suggest you use this feature during development and not worry about the portability aspect.

Q. How do I generate the tables with some specific columns being indexed?

If your column has a unique constraint associated with it, then you can use:

@Column(unique=true)

Otherwise, you can use columnDefinition in @Column to specify your own DDL.

Q. Does Java2DB generate constraints in the database?

Yes, it generates the appropriate primary keys, foreign keys etc.

Dependency Injection, JNDI lookup, EntityManager related questions

Q. I am getting a NullPointerException in my web application while trying to use the injected EntityManager. What is the problem?

This typically happens when you have a web.xml in your war file and its version < 2.5, i.e. it uses a schema or dtd from an earlier version of the spec. Injection only works for a Java EE 5 application, so your web application needs to be servlet 2.5 compliant. Refer to http://forums.java.net/jive/thread.jspa?forumID=56&threadID=14141 for more details.

Q. How should I get hold of an EntityManager in my Servlet?

Don't use @PersistenceContext to inject an EntityManager into a Servlet. This is discussed in greater detail at http://forums.java.net/jive/thread.jspa?forumID=56&threadID=16808
That article describes ways to use both an application managed as well as a container managed EntityManager. We recommend you use a container managed EntityManager.

Q. Can I use javax.persistence.Persistence.createEntityManagerFactory() to get hold of an EntityManagerFactory in my web application?

Yes, but this is not recommended because javax.persistence.Persistence.createEntityManagerFactory() is designed for use in a Java SE environment. In a Java EE environment, you can use dependency injection or JNDI lookup to access an EntityManagerFactory or an EntityManager as discussed earlier in this FAQ. Having said that, if you are using a web container like Tomcat 5.x which does not support Java Persistence API, then you have no option but to use this API. In such a case, we recommend you choose a container like GlassFish which supports the latest spec.

Q. Can I use a resource-local EntityManager in my web application?

Yes, you can use both resource-local as well as JTA EntityManager in your web application. The same applies to an EJB application as well. But, we recommend you use a JTA EntityManager in your web and EJB applications and use a resource-local EntityManager in your Java SE or Java EE client application.

Q. I am calling merge, yet the entity state is detached. What am I doing wrong?

<T> T merge(T entity) returns a new copy if the argument is a detached entity. So, you need to use the returned object after calling merge. This is a spec defined behavior. Refer to 3.2.4.1 of spec which says the following:

If X is a detached entity, the state of X is copied onto a pre-existing managed entity instance X' of the same identity or a new managed copy X' of X is created.

Refer to http://forums.java.net/jive/thread.jspa?threadID=15178 where a similar issue is discussed.

Q. I have called em.merge(e) and yet I am getting an IllegalArgumentException while trying to delete an entity from the database using em.remove(e). What am I doing wrong?

You have most probably ignored the return value of em.merge(). Refer to http://forums.java.net/jive/thread.jspa?forumID=56&threadID=16891 for more details.

Q. EntityManager.persist() throws TransactionRequiredException in a servlet. What am I doing wrong?

Refer to http://weblogs.java.net/blog/ss141213/archive/2005/12/entitymanagerpe_1.html

Miscellaneous Questions

Q. I am getting a “java.security.PrivilegedActionException : Error opening socket to server localhost on port 1527 message : nullError Code: 0”. What am I doing wrong?

The potential cause of this exception is that your Derby (a.k.a. JavaDB) database is not running. You can use “asadmin start-database" to start the database.

Q. What is the purpose of -javaagent option? What happens if I don't use it?

-javaagent:toplink-essentials-agent.jar is only useful when you have one-to-one or many-to-one lazily fetched relationships. If you omit it, your program will still work, but one-to-one and many-to-one relationships will be fetched eagerly. For more detail, please refer to http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/the_innermost_s.html

Q. How can I configure the cache used by TopLink Essentials?

There are various properties that you can use in your persistence.xml file to configure different aspects of cache used by TopLink Essentials. Please read http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-extensions.html#TopLinkCaching for more details.

Q. How do I configure the logging level for Toplink?

For both Java SE and EE, You can set the logging level for a persistence unit by using the following property:

<property name="toplink.logging.level" value="%DESIRED_LOGGING_LEVEL"/>

In GlassFish, you can set the global log level for all the persistence units using the admin GUI or asadmin CLI. The value specified in persistence.xml overrides the global log level. Please read
http://glassfish.java.net/javaee5/persistence/entity-persistence-support.html#Logging for more details.

Q. How can I see the sql generated by Toplink Essentials?

Set the logging level to FINE to see the sql generated by Toplink Essentials.

Q. How can I control the connection pool settings for an entity manager in a Java SE environment?

You can use the following properties in your persistence.xml to control the number of connections used by TopLink Essentials:

toplink.jdbc.read-connections.max
toplink.jdbc.read-connections.min
toplink.jdbc.read-connections.shared
toplink.jdbc.write-connections.max
toplink.jdbc.write-connections.min

as described in  http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-extensions.html#TopLinkJDBC