openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lemitja <mitja.le...@uni-mb.si>
Subject Re: Openjpa does not lazy fetch in OneToMany
Date Thu, 20 Nov 2008 19:26:29 GMT

I've noticed the same problem and can confirm bug in OpenJPA 1.2. It is not
limited to lazy fetches. The identity of the entity is incorrectly
determined in the case of polymorphic relation, consequently wrong SQL is
generated to retrieve data, which then results in orphaned message. The 
reference type is resolved to the same type as the owner relation class. In
your example the identity should be "com.bose.beans.Site-1502"" instead of
"com.bose.beans.Store-1502"

If this happens for the leaf classes, possible workaround is to use
@Nonpolymorphic annotation on @ManyToOne part of the relation.

 

Kuthiala, Amit wrote:
> 
>  I think what I am seeing might be a bug in openJPA. JPA is thinking it is
> an orphaned record but it does exist.I think it is going against the wrong
> table. I have an abstract superclass (Party) which is extended by Site and
> Store class. Site has one or more Stores and Store maps to one site. So
> there is a OneToMany relationship between them.
> 
> In my test cases I am creating a Store and passing in an existing site.
> (Code below). When I try to lazy fetch the Stores for a Site it works but
> If I try to get the site for a Store it gives me the message below.
> 
> Detected possible orphaned reference to deleted object
> "com.bose.beans.Store-1502" in "com.bose.beans.Store.site".
> 
> 
> Looking at the console it seems it is trying to go against the Store table
> when it should really be going against the Site table. Is openJPA getting
> confused because both Site and Store have the same Primary key PartyId
> from the superclass Party. Store has a field called SiteId that is a
> foreign key into Site.
> 
> 578        TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.SQL - <t
> 16749745, conn 1646156> executing prepstmnt 17860391 SELECT t0.PartyType,
> t0.version, t0.archiveStatus, t0.createDate, t0.status, t1.siteId,
> t1.storeDescription, t1.storeName FROM Store t1 INNER JOIN TranParty t0 ON
> t1.partyId = t0.partyId WHERE t1.partyId = ? [params=(long) 1502]
> 
> Here 1502 is a PartyId for Site but JPA is trying to find it in Store
> table.
> 
> -Amit
> 
> Details of the implementation and snapshots of classes, TestCases and
> Console log.
> 
> I have this hierarchy of classes. TranParty is the base class for both
> Site and Store. The Site has OnetoMany relationship with Store.
> 
> 
> 
> 
> [cid:image001.gif@01C91A45.C647CE30]
> 
> @Entity@Table(name = "Site")
> @DiscriminatorValue("Site")
> public class Site  extends Party implements java.io.Serializable {
> 
>       private static final long serialVersionUID = 1L;
>       private String SiteName;
>       private String SiteDescription;
>       private List<Store> stores;
> 
> @OneToMany(mappedBy="site", cascade=CascadeType.ALL, fetch=FetchType.LAZY,
> targetEntity=Store.class)
>       public List<Store> getStores() {
>             return stores;
>       }
> }
> 
> @Entity@Table(name = "Store")
> @DiscriminatorValue("Store")
> public class Store extends Party implements java.io.Serializable {
> 
>       private static final long serialVersionUID = 1L;
>       //private SystemSubscriber systemSubscriber;
>       private String StoreName;
>       private String StoreDescription;
>       private Site site;
>       private Long SiteId;
> 
>       @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY,
> targetEntity=Site.class)
>       @JoinColumn(name = "Store.SiteId",
> referencedColumnName="site.PartyId", nullable = false, insertable = true,
> updatable = true)
>       public Site getSite() {
>             return site;
>       }
> }
> 
> I am testing thorugh these methods. First creating a new Store with a Site
> and then testing if the Store can lazy load the Site. Lazy loading for
> Store from Site works fine. I get this error in the console.
> 
> 578  TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.SQL - <t
> 16749745, conn 1541717> executing prepstmnt 17726622 SELECT t0.PartyType,
> t0.version, t0.archiveStatus, t0.createDate, t0.status, t1.siteId,
> t1.storeDescription, t1.storeName FROM Store t1 INNER JOIN TranParty t0 ON
> t1.partyId = t0.partyId WHERE t1.partyId = ? [params=(long) 1552]
> 578  TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.SQL - <t
> 16749745, conn 1541717> [0 ms] spent
> 578  TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.JDBC - <t
> 16749745, conn 1541717> [0 ms] close
> 578  TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.SQL - <t
> 16749745, conn 1646156> executing prepstmnt 17860391 SELECT t0.PartyType,
> t0.version, t0.archiveStatus, t0.createDate, t0.status, t1.siteId,
> t1.storeDescription, t1.storeName FROM Store t1 INNER JOIN TranParty t0 ON
> t1.partyId = t0.partyId WHERE t1.partyId = ? [params=(long) 1502] - This
> SQL is executed when it tries to lazy fetch the Site. It looks like the
> query is wrong because it is going against the Store table instead of the
> Site table. The PartyId it is using is for the Site.
> 594  TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.SQL - <t
> 16749745, conn 1646156> [16 ms] spent
> 594  TestBosePersistenceUnit  TRACE  [main] openjpa.jdbc.JDBC - <t
> 16749745, conn 1646156> [0 ms] close
> 594  TestBosePersistenceUnit  WARN   [main] openjpa.Runtime - Detected
> possible orphaned reference to deleted object "com.bose.beans.Store-1502"
> in "com.bose.beans.Store.site".
> 
> 
> 
> 
> @Test
>       public void createNewStore() {
>             em.getTransaction().begin();
>             Store store = new Store();
>             store.setStoreDescription("storeDescription");
>             store.setStoreName("storeName");
>             store.setStatus("1");
>             store.setArchiveStatus("1");
>             store.setCreateDate(new Date());
> 
>             store.setSiteId(TestCaseHelper.getSiteIdCreated());
> 
>             Site site = em.find(Site.class,
> TestCaseHelper.getSiteIdCreated());
>             //store.setSiteId(site.getSiteId());
>             store.setSite(site);
>             List<Store> stores = new ArrayList<Store>();
>             stores.add(store);
>             site.setStores(stores);
> 
>             em.persist(store);
>             em.getTransaction().commit();
> 
>             em.refresh(store);
>             TestCaseHelper.setStoreIdCreated(store.getPartyId());
>             store = em.find(Store.class, store.getPartyId());
>             assertNotNull(store);
>       }
> 
> @Test
>       public void getStoreWithSite() {
>             Store store = em.find(Store.class,
> TestCaseHelper.getStoreIdCreated());
> 
>             assertNotNull(store);
> 
>             Site site = store.getSite();
>             assertNotNull(site);
> 
>       }
> 
> 
> 
> 

-- 
View this message in context: http://n2.nabble.com/Openjpa-does-not-lazy-fetch-in-OneToMany-tp1101139p1558514.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Mime
View raw message