Stackoverflow and vector errors based on JPA entitity objects

Hi. I am running Payara Community 5.2021.9 on a HA clustered architecture with 3 web nodes. Eclipselink is 2.7.9

2 JPA classes that refer to each other are giving me problems. I am also using some Lombok annotations such as @Data and @ToString so that may have to do with it.

#1 Load is a entity class that contains a reference to SalesOrderDetail and EmailTracker:

@Data @Builder @NoArgsConstructor @AllArgsConstructor 
public class Load implements Serializable
{

    private static final long serialVersionUID = 1L;
    @Id 
    @Basic(optional = false)
    @NotNull
    @Column(name = "LoadNum")
    private Integer LoadNum;
  
  ...

    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "LoadNum", referencedColumnName = "loadnum")
    private SalesOrderDetail salesOrder;
    
    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "LoadNum", referencedColumnName = "LoadNum")
    private EmailTracker emailLoadTracker;
    
}

#2 SalesOrderDetail Contains a reference to Load:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString(exclude = "header")
@EqualsAndHashCode(exclude = "header")
public class SalesOrderDetail implements Serializable
{
    private static final long serialVersionUID = 1L;
    @EmbeddedId
    protected SalesOrderDetailPK SalesOrderDetailPK;
    @Basic(optional = false)
    @NotNull
    @Column(name = "line_status")
    private Character lineStatus;

...


    @ManyToOne(cascade =
    {
        CascadeType.MERGE, CascadeType.REFRESH
    }, fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "vendor", referencedColumnName = "ven_cd")
    private Vendor vendorDetail;        
    
    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
    @JoinColumn(name = "loadnum", referencedColumnName = "loadnum", insertable = false, updatable = false)
    private Load Load;
       
}

When I try to run code that uses these classes I get this error:

 An exception or error occurred in the container during the request processing

java.lang.StackOverflowError
	at java.base/sun.util.locale.provider.TimeZoneNameUtility.retrieveDisplayNamesImpl(TimeZoneNameUtility.java:178)
	at java.base/sun.util.locale.provider.TimeZoneNameUtility.retrieveDisplayName(TimeZoneNameUtility.java:150)
	at java.base/java.util.TimeZone.getDisplayName(TimeZone.java:401)
	at java.base/java.util.Date.toString(Date.java:1046)
	at java.base/java.lang.String.valueOf(String.java:2951)
	at java.base/java.lang.StringBuilder.append(StringBuilder.java:168)
	at com.entities.SalesOrderDetail.toString(PlSalesOrderDetail.java:105)
	at java.base/java.lang.String.valueOf(String.java:2951)
	at java.base/java.lang.StringBuilder.append(StringBuilder.java:168)
	at com.entities.Load.toString(Load.java:62)

(A similar error occurs between Load and EmailTracker).

If I try to resolve it for example by changing Load’s @ToString to:

@ToString(exclude = {"emailLoadTracker","salesOrder"})

Or, when I comment out Load’s reference to salesOrder entirely,

then I get this error:

java.util.NoSuchElementException
	at java.base/java.util.Vector$Itr.next(Vector.java:1279)
	at org.eclipse.persistence.internal.helper.NonSynchronizedVector.toString(NonSynchronizedVector.java:403)
	at java.base/java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1422)
	at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1179)
	at java.base/java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1553)
	at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1510)
...

	at java.base/java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:1130)
	at java.base/java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1497)
...
	at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:114)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:569)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:549)
	at java.base/java.lang.Thread.run(Thread.java:834)
]]

Please note I’m not changing SalesOrderDetail’s @ToString to: @ToString(exclude = {“load”}). Maybe I should?

There doesn’t seem to be a way out of the two errors. I either get one or the other.

Any advice would be appreciated. Thanks.

Heya,

i guess, it is not right how you have annotated the OneToOne-relationships.

I do not know your database model. But it is so: this OneToOne-realationship, which has the foreign key, is the owner of this relationship and should be annotated with JoinColumn/PrimaryKeyJoinColumn. The inverse relationship should be annotated with:

@OneToOne(fetch=FetchType.LAZY, mappedBy=“nameOfTheRelationshipOwnerField”)

Cheers

1 Like