Deciphering EclipseLink Error Messages

Suppose you get this:

Descriptor Exceptions: 
---------------------------------------------------------
Exception [EclipseLink-108] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: Cannot find value in class indicator mapping in parent descriptor [null].
Descriptor: RelationalDescriptor(com.foobar.Foobar --> [DatabaseTable(FOOBAR)])
Exception [EclipseLink-41] (Eclipse Persistence Services - 2.6.2.v20151217-774c696): org.eclipse.persistence.exceptions.DescriptorException
Exception Description: A non-read-only mapping must be defined for the sequence number field.
Descriptor: RelationalDescriptor(com.foobar.Foobar --> [DatabaseTable(FOOBAR)])

That means, believe it or not, only that you have an abstract entity without any concrete entity specializing it.  That’s all it means.  It doesn’t have anything to do with sequence numbers, or (otherwise) badly mapped entities, or
updatable="false"
snippets.

EntityManager#contains(Object) Rolls Back the Transaction

A note for posterity: if you call EntityManager#contains(Object) on an object that is not known to that EntityManager, it will throw an IllegalArgumentException. When it does so, it irrevocably rolls the transaction back.

Instead, use something like this:


/**
* Returns {@code true} if the supplied {@link EntityManager} is
* non-{@code null} and contains the supplied {@link Object} in its
* persistence context. Unlike the {@link EntityManager#contains(Object)}
* method, this method will not throw any exceptions, and hence will
* never roll the containing transaction back.
*
* @param em the {@link EntityManager} in question; may be {@code null}
* in which case {@code false} will be returned
*
* @param o the {@link Object} to look for; may be {@code null} in which
* case {@code false} will be returned
*
* @return {@code true} if the supplied {@link Object} is a {@linkplain
* Metamodel#getManagedTypes() managed type} with respect to the supplied
* {@link EntityManager} and is also {@linkplain
* EntityManager#contains(Object) contained} by the supplied {@link
* EntityManager}; {@code false} otherwise
*/
public static final boolean contains(final EntityManager em, final Object o) {
boolean returnValue = false;
if (em != null && o != null) {
final Metamodel mm = em.getMetamodel();
if (mm != null) {
final Collection<?> types = mm.getManagedTypes();
returnValue = types != null && types.contains(o) && em.contains(o);
}
}
return returnValue;
}

view raw

gistfile1.java

hosted with ❤ by GitHub

Making EclipseLink Logging Play Nice With GlassFish 3.1.2.2

To get logging working properly with EclipseLink 2.3.2 and GlassFish 3.1.2.2, you want to configure the actual logging values in GlassFish’s logging.properties file, not in your META-INF/persistence.xml file.  You have to set two levels (a bit mysterious, as one is a child of the other; setting values on the parent logger should cause them to flow downhill, but for some reason they do not).

Then, to be able to see SQL parameters in the output, you have to set a property in your META-INF/persistence.xml file.

Assuming you have a domain called domain1:

  • Edit $GLASSFISH_HOME/glassfish/domains/domain1/config/logging.properties and add the following lines:
    1. org.eclipse.persistence.level = FINE
    2. org.eclipse.persistence.sql.level = FINE
      • The first allows you to see SQL statements.  The second must be set in order for SQL parameters to be seen, but it is not sufficient on its own.
  • In your META-INF/persistence.xml, add the following element as a child of the <properties> element:
    <property name="eclipselink.logging.parameters" value="true"/>

TableGenerators and Sequencing

So I learned today that your persistence.xml may have both a <jta-data-source> and a <non-jta-data-source> specified alongside each other. I’m not sure why I thought these were mutually exclusive but I figured someone else probably had this misunderstanding as well.

(I also was reminded of the fact that JDBC does not support nested transactions in a slightly related tangent.)

I also learned that some JPA providers can take advantage of a double listing: your run-of-the-mill JTA environment (such as an EJB server) will use the <jta-data-source> by default, but the other one might be used by your JPA provider. The JPA specification doesn’t really say anything about this; section 8.2.1.5 is about as close as it gets:

8.2.1.5  jta-data-source, non-jta-data-source
In Java EE environments, the jta-data-source and non-jta-data-source elements are used to specify the global JNDI name of the JTA and/or non-JTA data source to be used by the persistence provider. If neither is specified, the deployer must specify a JTA data source at deployment or a JTA data source must be provided by the container, and a JTA EntityManagerFactory will be created to correspond to it.

These elements name the data source in the local environment; the format of these names and the ability to specify the names are product specific.

In Java SE environments, these elements may be used or the data source information may be specified by other means—depending upon the requirements of the provider.

Specifically, EclipseLink can use your <non-jta-data-source> element if you instruct it—for example—to use a separate connection for @TableGenerator-based identity generation. Otherwise, your sequence table operations will be only as granular as the (potentially long, hairy) transactions that wrap them.

Obviously, your <jta-data-source> and <non-jta-data-source> had better be pointing at the same data source in this case.

File this under “Huh”.