JPA entity is not correctly passed from EJB to Pre

2019-09-08 09:18发布

问题:

I am trying to pass a set of JPA entity from the business tier to the presentation tier. All is deployed on the same app server (Glassfish 4). The client is deployed as a .war file, while the Business Tier as an .ear with the ejb reachable trough a Remote interface.

For this I have those very simple methods, with absolutely no logic:

Client

    public List<CompletedDesign> selectCompletedDesigns() {
        try {
            List<CompletedDesign> designs = customerFacade.selectCompletedDesigns();
            return designs;
        } catch (EJBException e) {
            e.printStackTrace();
        }
        return null;
    }

And in the ejb

// EJB
@Override
@RolesAllowed("customer")
public List<CompletedDesign> selectCompletedDesigns() {

    final Principal callerPrincipal = sessionCtx.getCallerPrincipal();

    String name = callerPrincipal.getName();
    Customer customer = dataXchangeBean.getCustomerByID(name);
    List<CompletedDesign> cds = customerBean.selectCompletedDesigns(customer);
    return cds;
}

Final this is a fragment of the JPA Entity.

@Entity
@Table(name = "COMPLETED_DESIGN")
@NamedQueries({......})
public class CompletedDesign implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 20)
    @Column(name = "ID")
    private String id;
    @Column(name = "DESCRIPTION")
    private String description;
    @Column(name = "NAME")
    private String name;
    @Column(name = "STATUS")
    private DesignStatus status;    
    @JoinColumn(name = "CUSTOMER_FK", referencedColumnName = "ID")
    @ManyToOne(optional = false, fetch = FetchType.LAZY)
    private Customer customerFk;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "designFk", fetch = FetchType.LAZY)
    private List<Product> products;

By putting a breakpoint I can see the cds list is correctly retrieved in the EJB side. The very first question would be, why I am getting a Vector instead of a List ? I am using a TypedQuery from the JPS side and that was supposed to correctly cast the object.

However my main concern is this: in the subsequent breakpoint on the client class itself in the presentation layer, it seems that it cannot fully reconstruct the object, the values are all null, and the type is missing. What am I missing here ?

回答1:

You are using LAZY loading, which means related objects will be loaded when you access them, and not when the primary object is loaded (so that they won't be loaded if you really don't need them). This however, does not work when the primary object is detached from the session. Therefore you must either use EAGER instead of lazy, or just load (access) the collections you need inside the transaction, before passed over the remote interface.



回答2:

After having spent days trying to make it work, I found this SO post, which brings to the most obvious solution, a bug with Glassfish and EclipseLink !!!

The SO post: EclipseLink deserializes an empty entity object on remote EJB call

The bug: eclipselink.weaving breaks marshalling out of the box