cancel
Showing results for 
Search instead for 
Did you mean: 

LazyLoading: dump with basic operation

former_member190457
Contributor
0 Kudos

Hi all,

I have two JPA entities: Company and Employee

Company is in a @OneToMany relationship with Employee

Employee is in a @ManyToOnw relationship with Company and owns the relationship

I have marked Employee's side as eager and Company side as lazy

I have developed a simple ejb which does something like this:

 
public void retrieveCompany(String id){
Company cmp = em.find(Company.class, id);
}

If I invoke this ejb from a WDJ or another EJB I get an odd error on lazy loading

 
Caused by: java.lang.ClassCastException
at java.lang.Class.cast(Class.java:2951)
at com.sap.engine.services.orpersistence.core.StoreManager.createLazyRelation(StoreManager.java:238)
at com.sap.engine.services.orpersistence.core.StoreManager.loadMultipleToManyRelationships(StoreManager.java:1349)
at com.sap.engine.services.orpersistence.core.StoreManager.processEntityInfos(StoreManager.java:1148)
at com.sap.engine.services.orpersistence.core.StoreManager.loadOrRefreshFromDB(StoreManager.java:226)
at com.sap.engine.services.orpersistence.core.StoreManager.loadEntityOrRefreshExisting(StoreManager.java:180)
at com.sap.engine.services.orpersistence.core.PersistenceContextImpl.loadEntityFromConnection(PersistenceContextImpl.java:247)
at com.sap.engine.services.orpersistence.core.PersistenceContextImpl.loadEntity(PersistenceContextImpl.java:262)
at com.sap.engine.services.orpersistence.core.PersistenceContextImpl.find0(PersistenceContextImpl.java:191)
at com.sap.engine.services.orpersistence.core.PersistenceContextImpl.find(PersistenceContextImpl.java:175)
at com.sap.engine.services.orpersistence.core.MonitoredPersistenceContextImpl.find(MonitoredPersistenceContextImpl.java:246)
at com.sap.engine.services.orpersistence.entitymanager.EntityManagerImpl.find(EntityManagerImpl.java:129)
at com.sap.engine.services.orpersistence.entitymanager.EntityManagerHandleImpl.find(EntityManagerHandleImpl.java:42)
at com.sap.engine.services.orpersistence.container.EntityManagerProxy.find(EntityManagerProxy.java:82)

This error is solved if I set Company's side of the relationship as EAGER, but this is not acceptable to me.

Can anyone please advice?

Thanks, regards

Vincenzo

Accepted Solutions (0)

Answers (1)

Answers (1)

former_member190457
Contributor
0 Kudos

hi all,

I found out what was missing:

As per JPA specifications relationships must be modeled using

Collection, Set, List, Map

AND NOTHING ELSE

you must not use ArrayList or whatever even though they implement those interfaces.

However, I would like to use this thread to define the final truth about SAP JPA lazy loading behavior:

In my WDJ model I call an EJB method which returns an entity which has a oneToMany relationship marked as lazy

The returned entity is detached and if nothing is specified you will get an "entity is detached" dump.

So: if you want your collection loaded from db, in your EJB you might use something like


myEntity.getMyCollection().size();

in this way I have checked that all the items in the collection are loaded and returned.

if you don't want you collection loaded you must use somethink like:


myEntity.setMyCollection(null);

So that it will kill the proxy which has been loaded in place of the actual collection object.

Please comment and report your experience, this is fundamental for everyone using SAP JPA implementation

Thanks, regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi,

I do not think web dynpro fits lazy loading, see this thread:

Other web User Interface technologies have patterns to support lazy loading, e.g. "open EntityManager in view"-pattern in spring / Web MVC.

Let me add something interesting, but off topic since this thread is about SAP JPA:

Another persistence provider - EclipseLink - supports lazy loading even on detached objects. Really! The detached object "knows" how to fetch its children. Not in @Remote scenarios, of course. I did not yet try in Web dynpro EJB models. If you have the same entity in two EJB models- one that needs the lazy part, one that does not - this could work with EclipseLink.

Regards,

Rolf

former_member190457
Contributor
0 Kudos

Hi Rolf,

Yes what is said in the thread you mention is true.

The WD model at runtime traverses the whole object tree.

This is why I suggest that in EJBs you explicitly set to null collections which are not required before returning.

If you don't do so, the WD runtime will traverse the object tree, find the proxy in place of the collection and then dump.

The EL feature you mention is really cool, will check it out asap.

Could you redirect to some resources specifying how to use EL (I have found only how to use Hibernate only in SAP NW)?

Thanks. regards

Vincenzo

rolf_paulsen
Active Participant
0 Kudos

Hi Vincenzo,

using EL is much easier than using hibernate because unlike hibernate, EL has no dependencies to common jars that are inside NW, therefore EL needs no "heavy classloading" and can be used like any 3rd party jar.

Some hints:

- With EL < 2.1, there is no built-in ServerPlatform for SAP Netweaver so you should look at

[http://dev.eclipse.org/mhonarc/lists/eclipselink-users/msg03158.html]

End of this month the final release of EL 2.1 will be out and NW will be built in EL.

[http://wiki.eclipse.org/EclipseLink/Development/ServerPlatform/NetweaverPlatform]

This link also describes how to use it in persistence.xml. As written above there is no need for an EL-sda. You can go with a external-libs DC as well.

- On Oracle Database, EL directly uses some Oracle features of the Oracle jdbc driver. So the ojdbc14.jar must be visible to EL and should be bundled in the same unit (DC or sda) as EL.

- Use a datasource with isolation level "read committed".

Regards,

Rolf

former_member190457
Contributor
0 Kudos

Hi Rolf,

thanks for your helpful answer. Will try EL asap

Thanks, regards

Vincenzo

Edited by: VINCENZO TURCO on Jun 7, 2010 4:21 PM

Former Member
0 Kudos

Hello Vicenzo,

Setting a property to null works only with collectiosn. I've tried to set a property of an Many-To-One Relation to null, but then the entity manager complaint, because he has trried to save the null value to the DB. In other word teh entity manager has tried to remove the Invoce from the InvoiceItem wich make no sense. To avoid this I've called the em.clear(); method bevor setting the Invoice of the InvoiceItem to null.

Now its works. But I'm not very happy because I think its poor design to add in every method of the session beans so code to set the object reference to null.

Did you find in the meantime a other better solution? Is there a option in WDj so set in the importet model with relations to load an witch not?

Thanks for your help in advance.

Sebastian