Re: Help - Error trying to run Jakarta Rest RSVP example from jakarta ee tutorial.

Richard Zowalla <[email protected]> Mon, 8 Jun 2026 07:43:52 +0200
Newsgroups gmane.comp.java.openejb.user
Message-ID <[email protected]>
OpenJPA does not implement Entity Graphs and is far away from being JPA =
3.1 compatible in its current version.
It might get JPA 3.2 compliance with the next release (there is an open =
PR for it).

Gru=C3=9F
Richard

> Am 08.06.2026 um 07:39 schrieb Gabriel Alejandro Soto Rivera =
<[email protected]>:
>=20
> Best regards to all.
> I continued working on the example and managed to get it working using
> one of the two
> methods. This was using Named Queries, whereas using NamedEntityGraph
> still gives me
> errors.
>=20
>=20
> =C2=ABNamed Queries=C2=BB
>=20
> To make it work with Named Queries, I created two queries in the form
> =E2=80=98SELECT DISTINCT ... JOIN FETCH ...=E2=80=99. The first query =
joined one of the entity=E2=80=99s
> one-to-many relationships, and the other joined the next one-to-many
> relationship. Both
> results were stored in the same list.
> Furthermore, I had to configure the entity enhancement at build time.
> This is because
> when I tried to use enhancement at deployment time with the property
> =E2=80=98openejb.jpa.deploy-time-enhancement=3Dtrue=E2=80=99, I =
received the following error when
> attempting to enhance the entities:
>    WARNING [main]
> org.apache.openejb.assembler.classic.DeployTimeEnhancer.enhance cannot
> enhance entities at deployment time
>        java.lang.reflect.InvocationTargetException ...
>    Caused by: java.lang.IllegalArgumentException ...
> And the entity causing the error has changed as I=E2=80=99ve been =
working on
> the example.
> What confuses me is that I get an error when trying to enhance the
> entity at deployment
> time, but not at build time. What=E2=80=99s more, if I don=E2=80=99t =
enhance the
> entity at build time,
> I get the previous error:
>    =
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemExcepti=
on
> EjbTransactionUtil.handleSystemException:
>    Cannot invoke
> =E2=80=98org.apache.openjpa.jdbc.meta.ClassMapping.getFieldMappings()=E2=
=80=99 because
> =E2=80=98cm=E2=80=99 is null
> when trying to test the example.
>=20
> I have included the log from the working example. Here, you can also
> see the error that
> occurs when attempting to enhance the entities at deployment time
> because the property
> =E2=80=98openejb.jpa.deploy-time-enhancement=3Dtrue=E2=80=99 is =
enabled.
> The log is called rsvp-working-openjpa-join-buildEnhancement
>=20
>=20
> =C2=ABNamedEntityGraph=C2=BB
>=20
> When I try to use NamedEntityGraph, I keep getting the same error. It
> says that the
> operation is not supported by JPA 2.1. This is odd, as according to
> the OpenJPA website,
> version 4.1.1 included in Tomee 10 is a JPA 3.1 implementation. The
> error is as follows:
>    =
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemExcepti=
on
> Ejb>
>        java.lang.UnsupportedOperationException: JPA 2.1
>            at =
org.apache.openjpa.persistence.EntityManagerImpl.getEntityGraph(EntityMana=
gerImpl.java:2126)
>            ...
> I have included the rest of the log in the file
> rsvp-error-openjpa-entity-graph-enh-ann
>=20
>=20
> You can find the updated example in the fork I created of the original
> project on my GitHub:
> =
https://github.com/Sxtormulo/jakartaee-examples/tree/main/tutorial/jaxrs/r=
svp.
>=20
> The example currently works correctly with named queries, as the POM
> uses tomee-maven-plugin
> and the OpenJPA plugin to enhance entities at build time.
> However, if you wish to reproduce the error with NamedEntityGraph, you
> can replace the
> file /src/main/java/jakarta/tutorial/rsvp/ejb/StatusBean.java with the
> StatusBean.java
> file that I will include in this email.
>=20
> Thank you all for your attention. And many thanks to Richard for his
> help, which enabled
> me to work through the example to this point.
> Best regards, Gabriel.
>=20
>=20
> El dom, 24 may 2026 a la(s) 1:08=E2=80=AFa.m., Gabriel Alejandro Soto =
Rivera
> ([email protected]) escribi=C3=B3:
>>=20
>> Kind regards.
>>=20
>> Thank you very much for your detailed reply. Your explanation of the =
problem helped me
>> start looking in the right places. To add, having looked at the =
example more closely, I
>> realise you=E2=80=99re right =E2=80=93 the code is a bit sloppy. Once =
I=E2=80=99ve sorted this issue out, I=E2=80=99ll
>> try to suggest some improvements via a pull request.
>>=20
>> Firstly, I made the specified changes. The example ran successfully, =
but the relevant
>> part of the website stopped working. This is because =
=E2=80=98EventManager.java=E2=80=99 needs to
>> retrieve the data declared as transient in the XML.
>>=20
>> So, I left the change to =E2=80=98pom.xml=E2=80=99 to continue using =
the tomee-maven-plugin but removed
>> the @XmlTransient tags.
>>=20
>> Whilst searching for more information with the cause of the problem =
in mind, I came across
>> this blog https://thorben-janssen.com/lazyinitializationexception/ =
which helped me find
>> two solutions to the problem.
>>=20
>> One option is to use =E2=80=98LEFT JOIN FETCH=E2=80=99 to tell JPA =
that I need to load not only the
>> entity, but also the entities related to it. The other is to use =
@NamedEntityGraph to
>> specify the relationships with their properties and likewise load the =
dependent entities.
>>=20
>> Neither option worked, and the following errors were encountered:
>> The option with =E2=80=98LEFT JOIN FETCH=E2=80=99 gave me the error:
>> =
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemExcepti=
on EjbTransactionUtil.handleSystemException: Cannot invoke =
=E2=80=98org.apache.openjpa.jdbc.meta.ClassMapping.getFieldMappings()=E2=80=
=99
>> because =E2=80=98cm=E2=80=99 is null
>> <openjpa-4.1.1-r9d2f5f8 nonfatal general error> =
org.apache.openjpa.persistence.PersistenceException:
>> Cannot invoke =
=E2=80=98org.apache.openjpa.jdbc.meta.ClassMapping.getFieldMappings()=E2=80=
=99 because =E2=80=98cm=E2=80=99 is null
>>=20
>> And the second option with @NamedEntityGraph gave me the following =
error:
>> =
org.apache.openejb.core.transaction.EjbTransactionUtil.handleSystemExcepti=
on EjbTransactionUtil.handleSystemException: JPA 2.1
>>    java.lang.UnsupportedOperationException: JPA 2.1
>>=20
>> So I tried changing the persistence provider in the =
tomee-maven-plugin from OpenJPA to
>> Hibernate. This made both options run successfully.
>>=20
>> Is there a problem with OpenJPA causing it not to work correctly?
>>=20
>> As before, I have attached the new errors encountered, which are:
>> * rsvp-error-with-openjpa-entity-graph, relating to running the =
example using
>>  @NamedEntityGraph.
>> * rsvp-error-with-openjpa-join-fetch: relating to the use of =E2=80=98L=
EFT JOIN FETCH=E2=80=99
>>=20
>> You can also find the changes I made to the example on my GitHub:
>> =
https://github.com/Sxtormulo/jakartaee-examples/tree/main/tutorial/jaxrs/r=
svp.
>> In the =E2=80=98StatusBean.java=E2=80=99 class, within the =
=E2=80=98getAllCurrentEvents=E2=80=99 method, I have commented
>> out the code to allow you to switch between the options and test =
both.
>>=20
>> Thank you very much for your help. Finally, I have a question =
unrelated to the problem:
>> what is the difference between the Tomee Maven plugin and the Tomee =
Embedded Maven plugin?
>>=20
>>=20
>>=20
>> El mar, 19 may 2026 a la(s) 12:45=E2=80=AFp.m., Richard Zowalla =
([email protected]) escribi=C3=B3:
>>>=20
>>> Hi,
>>>=20
>>> thanks for the detailed report and for taking the time to attach =
both log
>>> variants, that made it possible to reproduce locally on the first =
try.
>>>=20
>>> Short answer: this is not a bug in your code or in the tutorial =
sources.
>>>=20
>>> You have hit a known interaction between OpenJPA's lazy-load =
behaviour and
>>> JAX-RS (CXF) marshalling that runs *after* the EJB transaction has
>>> finished. GlassFish + EclipseLink masks the same code's problem =
because
>>> EclipseLink is more permissive about touching =
detached/closed-context
>>> proxies.
>>>=20
>>> I reproduced this with apache-tomee-plus-10.1.5 on Temurin 17 using =
the
>>> exact module you linked. Below is a complete breakdown plus a patch =
you
>>> can apply to your fork. The diff is also attached as rsvp-fix.patch.
>>>=20
>>> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
>>> 1) Why /status/all returns 500 in the "no openjpa trace" log
>>> =
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
>>>=20
>>> The relevant lines in your no-trace log are:
>>>=20
>>> WARNING ... =
org.apache.cxf.jaxrs.provider.JAXBElementProvider.writeTo
>>> <openjpa-4.1.1 fatal user error>
>>> org.apache.openjpa.util.InvalidStateException: The context has been
>>> closed. ...
>>> SEVERE ... Problem with writing the data, class
>>> org.apache.openjpa.kernel.DelegatingResultList, ContentType: =
application/xml
>>>=20
>>> What is actually happening, step by step:
>>>=20
>>> a) StatusBean#getAllCurrentEvents() executes
>>> em.createNamedQuery(...).getResultList()
>>> OpenJPA returns an *org.apache.openjpa.kernel.DelegatingResultList*.
>>> This is a lazy wrapper, iit does not fully materialise the rows.
>>> b) The @Stateless method returns. The container-managed JTA =
transaction
>>> commits, and the JPA persistence context is closed.
>>> c) Only *now* does CXF's JAXBElementProvider start iterating the =
list to
>>> marshal it to XML. While iterating, the DelegatingResultList tries =
to
>>> pull the next row from the underlying broker, finds the broker is
>>> closed, and throws InvalidStateException("The context has been
>>> closed"). CXF maps that to HTTP 500.
>>>=20
>>> The same pattern bites again one level deeper: JAXB walks the Event
>>> fields (you have @XmlAccessorType(XmlAccessType.FIELD)) and =
encounters
>>> two LAZY relations:
>>>=20
>>> - @OneToMany(mappedBy =3D "event") List<Response> responses
>>> - @ManyToMany List<Person> invitees
>>>=20
>>> By spec these default to FetchType.LAZY. They are still unresolved =
when the persistence context closes,
>>> so attempting to read them during marshalling fails for exactly the =
same
>>> reason.
>>>=20
>>> To answer the question you raised: yes, @ManyToOne defaults to
>>> FetchType.EAGER, and OpenJPA does honour that. I verified
>>> it by leaving Event.owner without @XmlTransient in the fix below; =
owner
>>> serialises correctly into the response payload, because it was =
already
>>> fully loaded inside the EJB transaction. So the eagerness behaviour =
you
>>> expect is working; only the LAZY-by-default collections needed
>>> intervention.
>>>=20
>>> The other endpoint, GET /status/{eventId}, works because it returns =
a
>>> single Event fetched with em.find(...), whose scalar fields and =
EAGER
>>> relations (owner) are fully loaded synchronously. Same reason
>>> ConfigBean and ResponseBean behave; they do not return lazy result
>>> sets.
>>>=20
>>> 2) About the "GlassFish works, TomEE doesn't" difference
>>>=20
>>> The tutorial code is sloppy (IMHO) in a way that EclipseLink =
tolerates and
>>> OpenJPA does not. The JPA spec leaves "what happens if you touch a =
lazy
>>> proxy after the persistence context is closed" largely
>>> implementation-defined; providers are free to throw. EclipseLink
>>> typically lets you read whatever state was already loaded and =
returns
>>> nulls/empties for the rest; OpenJPA is strict and raises
>>> InvalidStateException. Both behaviours are within spec; this is =
*not*
>>> "OpenJPA not being JPA-compliant". The tutorial just happens to be
>>> written in a way that exercises one of the edges where providers
>>> diverge. The right fix is at the application level (see below), not =
in
>>> the provider.
>>>=20
>>> 3.) The fix
>>>=20
>>> Two minimal application-side changes, no provider workarounds:
>>>=20
>>> (a) In StatusBean.getAllCurrentEvents(), wrap the result in a plain
>>> ArrayList so the data is materialised inside the EJB transaction:
>>>=20
>>> this.allCurrentEvents =3D new ArrayList<>(
>>> em.createNamedQuery("rsvp.entity.Event.getAllUpcomingEvents",
>>> Event.class).getResultList());
>>>=20
>>> After this, CXF marshals a plain java.util.ArrayList instead of an
>>> OpenJPA DelegatingResultList. No more "context has been closed" on
>>> the outer list.
>>>=20
>>> (b) In Event.java, mark the two LAZY collections @XmlTransient:
>>>=20
>>> @OneToMany(mappedBy =3D "event")
>>> @XmlTransient
>>> private List<Response> responses;
>>>=20
>>> @ManyToMany
>>> @XmlTransient
>>> protected List<Person> invitees;
>>>=20
>>> These collections are not part of what /status returns
>>> anyway (the endpoint reports events, not invitee/response graphs),
>>> and excluding them from XML/JSON serialisation means JAXB never
>>> tries to walk a LAZY proxy after the persistence context is closed.
>>> Event.owner stays as-is, because @ManyToOne is EAGER by default and
>>> is already loaded by the time the EJB returns.
>>>=20
>>> I have also added the tomee-maven-plugin to rsvp/pom.xml.
>>>=20
>>>            <plugin>
>>>                <groupId>org.apache.tomee.maven</groupId>
>>>                <artifactId>tomee-maven-plugin</artifactId>
>>>                <version>10.1.5</version>
>>>                <configuration>
>>>                    <tomeeVersion>10.1.5</tomeeVersion>
>>>                    <tomeeClassifier>plus</tomeeClassifier>
>>>                    <context>rsvp</context>
>>>                </configuration>
>>>            </plugin>
>>>=20
>>> That makes it trivial to reproduce / regression-test the example =
locally:
>>>=20
>>> mvn package
>>> mvn tomee:run
>>>=20
>>> and then GET http://localhost:8080/rsvp/webapi/status/all .
>>>=20
>>> Hope this helps - and good luck with the rest of the tutorial!
>>>=20
>>> Gru=C3=9F
>>> Richard
>>>=20
>>>=20
>>>=20
>>>=20
>>>> Am 17.05.2026 um 03:53 schrieb Gabriel Alejandro Soto Rivera =
<[email protected]>:
>>>>=20
>>>> Warm regards to everyone, and thank you very much in advance.
>>>>=20
>>>> I=E2=80=99m just starting to learn Jakarta EE and Tomee, so I=E2=80=99=
m not sure if this is the right
>>>> place to ask for help with my problem. But I think it is, because =
it=E2=80=99s related to Tomee.
>>>>=20
>>>> I=E2=80=99m learning about Jakarta EE using the tutorial on their =
website:
>>>> Jakarta EE Tutorial I=E2=80=99ve just modified the POMs so that =
they don=E2=80=99t use GlassFish
>>>> by default, but instead run on the Tomee server I=E2=80=99ve =
installed locally; and change the
>>>> persistence.xml to not use eclipse as persistence provider. And, so =
far, the examples
>>>> have been working correctly.
>>>>=20
>>>> I am using Tomee 10.0.5 with their default configurations, only and =
a user in tomcat-users
>>>> to access to the html manager. Then, to test if is the example that =
is not working or is Tomee
>>>> I installed GlassFish 7 and the example works well. But I want to =
make it work with Tomee.
>>>>=20
>>>> But I got stuck on the example in =E2=80=98Building RESTful Web =
Services with Jakarta REST=E2=80=99
>>>> The rsvp Example Application. Making some testing I discover that =
the endpoints of
>>>> ResponseBean.java works well; and ConfigBean.java make their job. =
But the problem
>>>> comes from executing the endpoints of StatusBean.java
>>>> However, when trying to debug, I get confusing logs depending on =
the configuration.
>>>> With the default configuration, the log indicates issues related to
>>>> =E2=80=98org.apach.cxf.jaxrs.provider.JAXBElementProvider=E2=80=99.
>>>> However, when adding
>>>> <property name=3D"openjpa.Log" value=3D"DefaultLevel=3DTRACE, =
Runtime=3DTRACE, Tool=3DTRACE"/>
>>>> to persistence.xml as the log suggests to obtain more information, =
the application fails
>>>> to deploy. It throws errors relating to
>>>> =E2=80=98jdk.internal.reflect.NativeMethodAccessorIpml.invoke=E2=80=99=
.
>>>> I have the tutorial code with the changes that i make to work with =
Tomee in my github:
>>>> =
https://github.com/Sxtormulo/jakartaee-examples/tree/main/tutorial/jaxrs/r=
svp.
>>>> These are the errors I get when I try to run the example with and =
without the openjpa.Log Trace
>>>> property in persistence.xml.
>>>> As I=E2=80=99m new to this, I=E2=80=99m not sure if it=E2=80=99s a =
configuration error, an app error or a bug.
>>>> If it is a bug, I=E2=80=99ll open an issue on GitHub to report it.
>>>> Thank you very much in advance for your help.
>>>=20
> <StatusBean.java>