I am trying to serialize Person
entities to JSON using a simple webservice, but I get the following exception:
12:27:44,923 SEVERE [org.eclipse.yasson.internal.SerializationContextImpl] (default task-1) Generating incomplete JSON
12:27:44,927 ERROR [org.jboss.resteasy.core.providerfactory.DefaultExceptionMapper] (default task-1) RESTEASY002375: Error processing request GET /bbstats/ws/person/findall - net.bbstats.webservice.PersonWebService.getPersonList: jakarta.ws.rs.ProcessingException: RESTEASY008205: JSON Binding serialization error jakarta.json.bind.JsonbException: Unable to serialize property 'player' from net.bbstats.entity.Person
at org.jboss.resteasy.resteasy-json-binding-provider@6.2.7.Final//org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider.asyncWriteTo(JsonBindingProvider.java:227)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.writeTo(ServerWriterInterceptorContext.java:81)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.asyncProceed(AbstractWriterInterceptorContext.java:190)
at org.jboss.resteasy.resteasy-crypto@6.2.7.Final//org.jboss.resteasy.security.doseta.DigitalSigningInterceptor.asyncAroundWriteTo(DigitalSigningInterceptor.java:142)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.asyncProceed(AbstractWriterInterceptorContext.java:196)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.AbstractWriterInterceptorContext.getStarted(AbstractWriterInterceptorContext.java:158)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.lambda$getStarted$0(ServerWriterInterceptorContext.java:68)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.aroundWriteTo(ServerWriterInterceptorContext.java:87)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.ServerWriterInterceptorContext.getStarted(ServerWriterInterceptorContext.java:68)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$3(ServerResponseWriter.java:166)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:365)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:243)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:100)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:73)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.SynchronousDispatcher.writeResponse(SynchronousDispatcher.java:518)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:458)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:240)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:154)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:321)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:157)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:229)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:222)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
at org.jboss.resteasy.resteasy-core@6.2.7.Final//org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
at jakarta.servlet.api@6.0.0//jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
at deployment.bbstats-3.0.war//net.bbstats.framework.filter.NoCacheFilter.doFilter(NoCacheFilter.java:33)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.security.elytron-web.undertow-server@4.0.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.lambda$handleRequest$1(ElytronRunAsHandler.java:68)
at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.FlexibleIdentityAssociation.runAsFunctionEx(FlexibleIdentityAssociation.java:103)
at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.Scoped.runAsFunctionEx(Scoped.java:161)
at org.wildfly.security.elytron-base@2.2.3.Final//org.wildfly.security.auth.server.Scoped.runAs(Scoped.java:73)
at org.wildfly.security.elytron-web.undertow-server@4.0.0.Final//org.wildfly.elytron.web.undertow.server.ElytronRunAsHandler.handleRequest(ElytronRunAsHandler.java:67)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.core@2.3.10.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.core@2.3.10.Final//io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.core@2.3.10.Final//io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at org.wildfly.security.elytron-web.undertow-server-servlet@4.0.0.Final//org.wildfly.elytron.web.undertow.server.servlet.CleanUpHandler.handleRequest(CleanUpHandler.java:38)
at io.undertow.core@2.3.10.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:44)
at io.undertow.core@2.3.10.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.deployment.GlobalRequestControllerHandler.handleRequest(GlobalRequestControllerHandler.java:51)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52)
at io.undertow.core@2.3.10.Final//io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at org.wildfly.extension.undertow@31.0.0.Final//org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$UndertowThreadSetupAction.lambda$create$0(UndertowDeploymentInfoService.java:1413)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256)
at io.undertow.servlet@2.3.10.Final//io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:101)
at io.undertow.core@2.3.10.Final//io.undertow.server.Connectors.executeRootHandler(Connectors.java:393)
at io.undertow.core@2.3.10.Final//io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1990)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
at org.jboss.threads@2.4.0.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1348)
at org.jboss.xnio@3.8.12.Final//org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: jakarta.json.bind.JsonbException: Unable to serialize property 'player' from net.bbstats.entity.Person
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ObjectSerializer.lambda$serialize$0(ObjectSerializer.java:43)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ObjectSerializer.serialize(ObjectSerializer.java:38)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.RecursionChecker.serialize(RecursionChecker.java:38)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.KeyWriter.serialize(KeyWriter.java:41)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullVisibilitySwitcher.serialize(NullVisibilitySwitcher.java:40)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.findSerializer(ObjectTypeSerializer.java:68)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serializeValue(ObjectTypeSerializer.java:50)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.TypeSerializer$ValueSerializer.serialize(TypeSerializer.java:51)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.TypeSerializer.serialize(TypeSerializer.java:37)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serialize(ObjectTypeSerializer.java:31)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.CollectionSerializer.lambda$serialize$0(CollectionSerializer.java:37)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.CollectionSerializer.serialize(CollectionSerializer.java:37)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.KeyWriter.serialize(KeyWriter.java:41)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullVisibilitySwitcher.serialize(NullVisibilitySwitcher.java:40)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.SerializationContextImpl.serializeObject(SerializationContextImpl.java:197)
at org.eclipse.yasson//org.eclipse.yasson.internal.SerializationContextImpl.marshall(SerializationContextImpl.java:133)
at org.eclipse.yasson//org.eclipse.yasson.internal.SerializationContextImpl.marshall(SerializationContextImpl.java:159)
at org.eclipse.yasson//org.eclipse.yasson.internal.JsonBinding.toJson(JsonBinding.java:121)
at org.jboss.resteasy.resteasy-json-binding-provider@6.2.7.Final//org.jboss.resteasy.plugins.providers.jsonb.ManagedJsonb.toJson(ManagedJsonb.java:78)
at org.jboss.resteasy.resteasy-json-binding-provider@6.2.7.Final//org.jboss.resteasy.plugins.providers.jsonb.JsonBindingProvider.asyncWriteTo(JsonBindingProvider.java:217)
... 72 more
Caused by: jakarta.json.bind.JsonbException: Unable to serialize property 'person' from net.bbstats.entity.Player
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ObjectSerializer.lambda$serialize$0(ObjectSerializer.java:43)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ObjectSerializer.serialize(ObjectSerializer.java:38)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.RecursionChecker.serialize(RecursionChecker.java:38)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.KeyWriter.serialize(KeyWriter.java:41)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullVisibilitySwitcher.serialize(NullVisibilitySwitcher.java:40)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.findSerializer(ObjectTypeSerializer.java:68)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serializeValue(ObjectTypeSerializer.java:50)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.TypeSerializer$ValueSerializer.serialize(TypeSerializer.java:51)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.TypeSerializer.serialize(TypeSerializer.java:37)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serialize(ObjectTypeSerializer.java:31)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ValueGetterSerializer.serialize(ValueGetterSerializer.java:43)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ObjectSerializer.lambda$serialize$0(ObjectSerializer.java:41)
... 96 more
Caused by: jakarta.json.bind.JsonbException: Recursive reference has been found in class class net.bbstats.entity.Person.
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.RecursionChecker.serialize(RecursionChecker.java:36)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.KeyWriter.serialize(KeyWriter.java:41)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullVisibilitySwitcher.serialize(NullVisibilitySwitcher.java:40)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.CyclicReferenceSerializer.serialize(CyclicReferenceSerializer.java:39)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.findSerializer(ObjectTypeSerializer.java:68)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serializeValue(ObjectTypeSerializer.java:50)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.TypeSerializer$ValueSerializer.serialize(TypeSerializer.java:51)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.TypeSerializer.serialize(TypeSerializer.java:37)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.types.ObjectTypeSerializer.serialize(ObjectTypeSerializer.java:31)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.NullSerializer.serialize(NullSerializer.java:67)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ValueGetterSerializer.serialize(ValueGetterSerializer.java:43)
at org.eclipse.yasson//org.eclipse.yasson.internal.serializer.ObjectSerializer.lambda$serialize$0(ObjectSerializer.java:41)
... 110 more
Some recursion checker is complaining. This used to work using Java EE 8.
I simply want to show a list of person that have the roles as a player, a coach or a referee. A person can have all three roles, any combination of the three or none at all.
Contact abstract/super entity;
@Entity
@Table(name = "\"Contacts\"")
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
@XmlRootElement
public abstract class Contact implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column
protected Integer id;
@Basic(optional = false)
@Column(insertable = false, updatable = false)
@Convert(converter = ContactTypeConverter.class)
protected ContactType type;
...
}
Person entity;
@Entity
@Table(name = "\"Persons\"")
@DiscriminatorValue("P")
@NamedQuery(name = Person.FIND_ALL, query = "SELECT pe FROM Person pe ORDER BY pe.lastName, pe.firstName")
@NamedEntityGraph(name = Person.FETCH_EMAIL_ADDRESSES_PHONE_NUMBERS_AND_ROLES,
attributeNodes = {
@NamedAttributeNode(value = "player"),
@NamedAttributeNode(value = "coach"),
@NamedAttributeNode(value = "referee")}
)
public class Person extends Contact
{
private static final long serialVersionUID = 1L;
public static final String FIND_ALL = "Person.findAll";
public static final String FETCH_ROLES = "Person.fetchRoles";
@Basic(optional = false)
@Column(name = "first_name")
private String firstName;
@Basic(optional = false)
@Column(name = "last_name")
private String lastName;
@Basic(optional = false)
@Column
@Enumerated(EnumType.STRING)
private PersonGender gender = PersonGender.MALE;
@Basic
@Column(name = "birth_date")
private LocalDate birthDate;
@Basic(optional = false)
@Column(name = "is_incognito")
private Boolean incognito = Boolean.FALSE;
@OneToOne(mappedBy = "person", fetch = FetchType.LAZY)
private Coach coach;
@OneToOne(mappedBy = "person", fetch = FetchType.LAZY)
private Player player;
@OneToOne(mappedBy = "person", fetch = FetchType.LAZY)
private Referee referee;
...
}
Player entity (possible role #1);
@Entity
@Table(name = "\"Players\"")
@XmlRootElement
public class Player implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column
private Integer id;
@Basic
@Column(name = "registration_nbr")
private String registrationNbr;
@OneToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "id", insertable = false, updatable = false)
@XmlTransient
private Person person;
...
}
Coach entity (possible role #2);
@Entity
@Table(name = "\"Coaches\"")
@XmlRootElement
public class Coach implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column
private Integer id;
@Basic
@Column(name = "license_nbr")
private String licenseNbr;
@OneToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "id", insertable = false, updatable = false)
@XmlTransient
private Person person;
...
}
Referee entity (possible role #3);
@Entity
@Table(name = "\"Referees\"")
@XmlRootElement
public class Referee implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column
private Integer id;
@Basic
@Column(name = "license_nbr")
private String licenseNbr;
@OneToOne(optional = false, fetch = FetchType.EAGER)
@JoinColumn(name = "id", insertable = false, updatable = false)
@XmlTransient
private Person person;
...
}
As you can see I wasn't able to use inheritance for Player
, Referee
and Coach
. JPA is specified to only support total inheritance. So basically, there's a simple @OneToOne
mapping for each role.
Note that there's @DiscriminatorValue("P")
on the Person
entity, because there are persons, clubs and arenas, which can generally be contacted and are derived from Contact
via real @Inheritance(strategy = InheritanceType.JOINED)
(see entity above). I omitted those in my example.
PersonWebService:
@Path("/person")
public class PersonWebService {
@Inject
private PersonService personService;
@GET
@Path("/findall")
@Produces(MediaType.APPLICATION_JSON)
public List<Person> getPersonList() {
List<Person> persons = personService.findAllWithFetchGraph(Person.FETCH_ROLES); // <-- EXCEPTION!
return persons;
}
@GET
@Path("/find/{id}")
@Produces(MediaType.APPLICATION_JSON)
public Person getPerson(@PathParam("id") Integer id) {
Person person = personService.findByPk(id);
return person;
}
}
Here's the error again:
RESTEASY008205: JSON Binding serialization error jakarta.json.bind.JsonbException: Unable to serialize property 'player' from net.bbstats.entity.Person
QUESTION:
What's wrong here?
Why is there an exception being thrown, given that Player.person
is declared as @XmlTransient private Person person;
? This happens for all role entities BTW. I want all persons to serialize the three roles into JSON for further processing.
My setup is Jakarta EE 10 using WildFly 31.0.0.Final. Basically everything being used (class-loaded) is coming from there, as-is. I have no special webapp libraries regarding webservices/JSON.
RESTeasy seems to be 6.0.0.Beta1.
WildFly 31 and RESTEasy use Jakarta JSON Binding as the default JSON object serializer. The XML binding annotations do not work there. You either need to change the annotations to use the Jakarta JSON Binding annotations or switch to using Jackson as the JSON serializer 2.
If you want to use Jackson for all deployments by default you can change the resteasy-prefer-jackson-over-jsonb
. With CLI the command would be:
/subsystem=jaxrs:write-attribute(name=resteasy-prefer-jackson-over-jsonb, value=true)
FWIW the RESTEasy version for WildFly 31 is 6.2.7.Final.