Iain,
Can you expand on this?

On Wed, Mar 26, 2008 at 10:04 PM, iain <[EMAIL PROTECTED]> wrote:

> FWIW, if I remove the inheritance of the MappedSuperclass, the enhancer
> has no trouble with my application and things operate as they should.


What exactly are you referring to when you say that you "remove the
inheritance"?  Removing the @Inheritance annotation?  Or, actually removing
the "extends" clauses?  Although, if it's the latter, then how does your
application work as it should?  You have provided a lot of good information
for this problem.  I'm just trying to figure out what exactly you changed to
get this to "work".

Thanks,
Kevin



> This seems to indicate that there is a problem with enhancing
> inheritance heirarchies, and certainly looks to have something to do
> with cycle detection, but I don't know the OpenJPA code so that is
> speculation at best
>
> At this stage, I'd recommend steering clear of inheritance...
>
> Cheers, Iain
>
> iain wrote:
> > Last month another user posted the following message to the mailing
> > list but no-one
> > was able to help:
> >
> >
> http://mail-archives.apache.org/mod_mbox/openjpa-users/200802.mbox/ajax/[EMAIL
>  PROTECTED]
> >
> >
> > I'm posting a follow-up because I'm experiencing the same symptom with
> > openjpa-1.0.2.
> >
> > My scenario is a little different to the previous post, and I'll try
> > to summarise here.
> > If I need to post more detail, just let me know. There is something
> > strange happening here if
> > you can make it through to the end where I describe a "work-around" to
> > the out-of-memory condition.
> >
> > First, here is the tail-end of the trace when I startup my application.
> > I'll reproduce the comment in the OpenJPA code for
> > MetaDataRepository.processBuffer - it sounds relevant:
> >
> >        // continually pop a metadata and process it until we run out;
> > note
> >        // that each processing call might place more metas in the
> > buffer as
> >        // one class tries to access metadata for another; also note
> > that the
> >        // buffer orders itself from least to most derived
> >
> >
> > Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError:
> > Java heap space
> >        at java.util.ArrayList.ensureCapacity(ArrayList.java:169)
> >        at java.util.ArrayList.add(ArrayList.java:351)
> >        at
> > org.apache.openjpa.meta.MetaDataRepository.processBuffer(
> MetaDataRepository.java:676)
> >
> >        at
> > org.apache.openjpa.meta.MetaDataRepository.resolveMeta(
> MetaDataRepository.java:575)
> >
> >        at
> > org.apache.openjpa.meta.MetaDataRepository.resolve(
> MetaDataRepository.java:500)
> >
> >        at
> > org.apache.openjpa.meta.MetaDataRepository.getMetaData(
> MetaDataRepository.java:302)
> >
> >        at
> > org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:241)
> >        at
> > org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:212)
> >        at
> > org.apache.openjpa.enhance.PCEnhancer.<init>(PCEnhancer.java:182)
> >        at
> >
> org.apache.openjpa.enhance.ManagedClassSubclasser.prepareUnenhancedClasses
> (ManagedClassSubclasser.java:119)
> >
> >        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> >        at
> > sun.reflect.NativeMethodAccessorImpl.invoke(
> NativeMethodAccessorImpl.java:39)
> >
> >        at
> > sun.reflect.DelegatingMethodAccessorImpl.invoke(
> DelegatingMethodAccessorImpl.java:25)
> >
> >        at java.lang.reflect.Method.invoke(Method.java:585)
> >        at
> > org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(
> AbstractBrokerFactory.java:297)
> >
> >        at
> > org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(
> AbstractBrokerFactory.java:199)
> >
> >        at
> > org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(
> DelegatingBrokerFactory.java:142)
> >
> >        at
> >
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager
> (EntityManagerFactoryImpl.java:192)
> >
> >        at
> >
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager
> (EntityManagerFactoryImpl.java:145)
> >
> >        at
> >
> org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager
> (EntityManagerFactoryImpl.java:56)
> >
> >        at
> > au.com.crabhill.hydrogeoreports.ORMHelper.openSession(ORMHelper.java:38)
> >        at
> > au.com.crabhill.hydrogeoreports.ClientModel.reloadClients(
> ClientModel.java:206)
> >
> >        at
> > au.com.crabhill.hydrogeoreports.ClientModel.<init>(ClientModel.java:31)
> >        at
> > au.com.crabhill.hydrogeoreports.HydrogeoReportsView.<init>(
> HydrogeoReportsView.java:69)
> >
> >        at
> > au.com.crabhill.hydrogeoreports.HydrogeoReportsApp.startup(
> HydrogeoReportsApp.java:19)
> >
> >        at
> > org.jdesktop.application.Application$1.run(Application.java:171)
> >        at
> > java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
> >        at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
> >        at
> > java.awt.EventDispatchThread.pumpOneEventForHierarchy(
> EventDispatchThread.java:242)
> >
> >        at
> > java.awt.EventDispatchThread.pumpEventsForHierarchy(
> EventDispatchThread.java:163)
> >
> >        at
> > java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
> >        at
> > java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
> >
> > OK, so I seem to have the PCEnhancer thrashing about trying to work
> > out my class metadata,
> > so here are the relevant bits (at least I hope the relevant bits):
> >
> > @MappedSuperclass
> > public abstract class ContactMech extends AbstractBean  implements
> > Serializable {
> >  // @Id field omitted for brevity
> >
> >    @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
> >    @ForeignKey
> >    @JoinColumn(name = "client_id", referencedColumnName = "client_id",
> > nullable=false)
> >    protected Client clientId;
> >  // This is a bidirectional parent-child mapping and the parent class
> > (Client)
> >  // includes the required 'mappedBy' attribute in the corresponding
> >  // @OneToMany
> >
> >       @ManyToOne(cascade = {CascadeType.MERGE, CascadeType.REFRESH})
> >    @ForeignKey
> >    @JoinColumn(name = "contact_mech_type_id", referencedColumnName =
> > "type_id", nullable=false)
> >    protected ContactMechType contactMechTypeId;
> >  // This is a unidirectional mapping, so no 'mappedBy' in TypeClass
> >  ...
> > }
> >
> > @Entity
> > @Table(name = "client")
> > public class Client implements Serializable {
> >  // @Id field omitted for brevity
> >
> >  // See below for the owning side of these bidirectional
> relationships...
> >    @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE,
> > CascadeType.REMOVE, CascadeType.REFRESH}, mappedBy = "clientId")
> >    @OrderBy("emailAddress ASC")
> >    private List<CMEmail> emails;
> >       @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE,
> > CascadeType.REMOVE, CascadeType.REFRESH}, mappedBy = "clientId")
> >    @OrderBy("areaCode ASC, phoneNum ASC")
> >    private List<CMTelecom> telecoms;
> >       @OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.MERGE,
> > CascadeType.REMOVE, CascadeType.REFRESH}, mappedBy = "clientId")
> >    private List<CMAddress> addresses;
> > ...
> > }
> >    Note in the following there is a self-referencing mapping
> > (implementing a type hierarchy).
> > @Entity
> > @Table(name = "contact_mech_type")
> > public class ContactMechType implements Serializable {
> >    @Id
> >    @Column(name = "type_id", nullable = false)
> >    private String typeId;
> >       @ManyToOne(fetch = FetchType.EAGER)
> >    @ForeignKey
> >    @JoinColumn(name = "parent_type_id", referencedColumnName =
> > "type_id", nullable = true)
> >    private ContactMechType parentType;
> >     // This is the inverse of the above
> >    @OneToMany(fetch = FetchType.EAGER, mappedBy = "parentType")
> >    private List<ContactMechType> subTypes;
> > ...
> > }
> >
> > Then I have three (3) subclasses of ContactMech which add an extra few
> > fields, one of
> > which is a JoinTable mapping:
> >
> > @Entity
> > @Table(name = "email")
> > // Do I need the following if I don't plan to inherit from THIS class.
> > Obviously I inherit from the MappedSuperclass above,
> > // but not sure what effect the @Inheritance annotation has on this
> > class.
> > @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
> > public class CMEmail extends ContactMech implements Serializable {
> >  // Simple @Column fields ommitted for brevity
> >
> >  // More on this one in a minute       @ManyToMany(fetch =
> > FetchType.EAGER)
> >    @JoinTable(
> >        name = "email_purpose",        joinColumns = [EMAIL PROTECTED](name
> > = "contact_mech_id", referencedColumnName = "contact_mech_id")},
> >        inverseJoinColumns = [EMAIL PROTECTED](name = "purpose_type_id",
> > referencedColumnName = "purpose_id")}
> >    )
> >    private List<ContactMechPurposeType> purposes;
> > ...
> > }
> >
> > @Entity
> > @Table(name = "telecom")
> > @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
> > public class CMTelecom extends ContactMech implements Serializable {
> >
> >  // As above, but we use a different JoinTable...
> >    @ManyToMany(fetch = FetchType.EAGER)
> >    @JoinTable(
> >        name = "telecom_purpose",        joinColumns =
> > [EMAIL PROTECTED](name = "contact_mech_id", referencedColumnName =
> > "contact_mech_id")},
> >        inverseJoinColumns = [EMAIL PROTECTED](name = "purpose_type_id",
> > referencedColumnName = "purpose_id")}
> >    )
> >    private List<ContactMechPurposeType> purposes;
> > ...
> > }
> >
> > @Entity
> > @Table(name = "address")
> > @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
> > public class CMAddress extends ContactMech implements Serializable {
> >
> >  // Ditto    @ManyToMany(fetch = FetchType.EAGER)
> >    @JoinTable(
> >        name = "address_purpose",        joinColumns =
> > [EMAIL PROTECTED](name = "contact_mech_id", referencedColumnName =
> > "contact_mech_id")},
> >        inverseJoinColumns = [EMAIL PROTECTED](name = "purpose_type_id",
> > referencedColumnName = "purpose_id")}
> >    )
> >    private List<ContactMechPurposeType> purposes;
> > ...
> > }
> >
> > Last but not least...
> >
> > @Entity
> > @Table(name = "contact_mech_purpose_type")
> > public class ContactMechPurposeType implements Serializable {
> >  // Omitted @Id field and various @Column fields for brevity
> >
> >    @ManyToOne
> >    @ForeignKey
> >    @JoinColumn(name = "type_id", referencedColumnName = "type_id",
> > nullable=false)
> >    private ContactMechType typeId;
> > ...
> > }
> >
> > What concerns me about my class network is circular references and
> > what PCEnhancer is doing to
> > them (given the comment I pasted from the OpenJPA source, above).
> >
> > To summarise, here's the reference table for all the classes above
> > (and which classes they references):
> >
> > Client:                 CMEmail, CMTelecom, CMAddress
> >  - these references are all backpointers in bidirectionals
> > CMEmail:                Client, ContactMechType, ContactMechPurposeType
> > CMTelecom:              Client, ContactMechType, ContactMechPurposeType
> > CMAddress:              Client, ContactMechType, ContactMechPurposeType
> >  - In the above 3, Client and ContactMechType references are via
> > inheritance of ContactMechType
> > ContactMechType:        ContactMechType (self-reference)
> > ContactMechPurposeType: ContactMechType
> >
> > NOW FOR THE WIERD BIT...
> >
> > If I change my Client class (above) to temporarily "disable" any one
> > of the mappings 'emails',
> > 'addresses', 'telecoms', by tagging the field as @Transient instead of
> > a backpointer to the
> > bidirectional mapping, this makes the mapping unidirectional at the
> > other end, obviously.
> >
> > When I do this, I don't get the PCEnhancer memory-slurp problem, and
> > the application runs!?!?!
> > (except for the bits that rely on the disable field). Note I only have
> > to disable ONE of these
> > backpointers for things get past the memory slurp.
> >
> > Help!!!
> >
> > And thanks for your patience if got this far...
> >
> > Cheers, Iain
> >
> >
> >
>
>
>
> --
> No virus found in this outgoing message.
> Checked by AVG.
> Version: 7.5.519 / Virus Database: 269.22.0 - Release Date: 24/03/2008
> 12:00 AM
>
>

Reply via email to