openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Michael Dick" <michael.d.d...@gmail.com>
Subject Re: JPAAnnotations on the instance variable or on the getter
Date Mon, 21 Apr 2008 15:20:04 GMT
Hi Lars,

It looks like you aren't hitting the same problem I was.

Are you running the PCEnhancer tool to enhance your entity classes? I've
been able to reproduce the problem on OpenJPA 1.0.2 if the entities aren't
enhanced prior to running the test.

You'll see something like this in the logs if the entities haven't been
enhanced :
1756  people  INFO   [main] openjpa.Enhance - Creating subclass for "[class
datamodel.impl.Person, class datamodel.impl.Job]". This means that your
application will be less efficient and will consume more memory than it
would if you ran the OpenJPA enhancer. Additionally, lazy loading will not
be available for one-to-one and many-to-one persistent attributes in types
using field access; they will be loaded eagerly instead.

Could you try enhancing the entities and see if that resolves the problem?
The OpenJPA manual covers enhancement at the following location :
http://openjpa.apache.org/docs/latest/manual/manual.html#ref_guide_pc_enhance

-Mike


On Mon, Apr 21, 2008 at 1:21 AM, Lars Vogel <lars.vogel@googlemail.com>
wrote:

> Hi Mike,
>
> even if I remove the @OrderBy annotation the error occurs. It seems that
> JPA
> cannot access the content of the list List<Jobs>. Please see my response
> to
> Janko.
>
> Best regards, Lars
>
>
> 2008/4/16, Michael Dick <michael.d.dick@gmail.com>:
> >
> > Hi Janko and Lars
> >
> > I'd forgotten about the restriction. When I saw that there was different
> > behavior between property and field access I guessed it was something
> with
> > the access level of his fields - maybe something in the subclassing
> > support.
> >
> >
> > I took a closer look at the example and I think the problem of is that
> it
> > uses a List of Strings as the target of the @OrderBy annotation. The
> > target
> > of the @OrderBy annotation is expected to be an entity which is causing
> a
> > NPE.
> >
> > I'm not sure it was the same NPE that Lars hit though. Here's what I've
> > been
> > seeing (with OpenJPA 1.2.0-SNAPSHOT):
> >
> > java.lang.NullPointerException
> >     at
> > org.apache.openjpa.meta.FieldMetaData.getOrders(FieldMetaData.java:1127)
> >     at
> >
> >
> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.selectEager(StoreCollectionFieldStrategy.java:209)
> >     at
> >
> >
> org.apache.openjpa.jdbc.meta.strats.StoreCollectionFieldStrategy.selectEagerJoin(StoreCollectionFieldStrategy.java:174)
> >     at
> >
> >
> org.apache.openjpa.jdbc.meta.FieldMapping.selectEagerJoin(FieldMapping.java:713)
> > <snip>
> >
> > What's confusing is that I ran into the problem regardless of the access
> > type.
> >
> > Lars, if you're seeing the same NPE then I think you can resolve the
> issue
> > by creating an Entity for the nickname field, or removing the @OrderBy
> > annotation.
> >
> > If this does resolve the problem and you would like to use the @OrderBy
> > annotation along with @PersistentCollection, please open a JIRA at
> > http://issues.apache.org/jira/browse/OPENJPA.
> >
> > Sorry for the red herring last night and I hope this helps,
> >
> > -Mike
> >
> >
> >
> > On Tue, Apr 15, 2008 at 12:50 AM, Janko Heilgeist <
> > janko.heilgeist@rzg.mpg.de> wrote:
> >
> > > Hi Michael,
> > >
> > > Michael Dick wrote:
> > >
> > > > If you put the annotations on a get or set method then the JPA
> > > > provider will expect property access to be used (ie
> > > > PersonNew.setFirstName("John")).
> > > >
> > >
> > > JPA specification, section 2.1.1:
> > >
> > > "[...] When property-based access is used, the object/relational
> mapping
> > > annotations for the entity class annotate the getter property
> > accessors[2].
> > > [...]
> > >
> > > [2] These annotations must not be applied to the setter methods."
> > >
> > >  In the example below the fields are private which is probably the
> > > > root problem when you use field access.
> > > >
> > >
> > > JPA specification, section 2.1.1:
> > >
> > > "[...] The persistent state of an entity is represented by instance
> > > variables [...] Instance variables must be private, protected, or
> > package
> > > visibility. [...]"
> > >
> > > So this should not be the problem. But I can't see anything wrong
> > either.
> > > Lars, can you post the stacktrace of your NPE?
> > >
> > > Regards, Janko
> > >
> > >
> > >
> > >
> > > > Have you tried making the fields public in the Person class you
> > > > provided?
> > > >
> > > > hth, Mike
> > > >
> > > >
> > > >
> > > > On Mon, Apr 14, 2008 at 2:04 AM, Lars Vogel
> > > > <lars.vogel@googlemail.com> wrote:
> > > >
> > > >  Hi,
> > > > >
> > > > > my understanding so far was that it doesn't matter if I have the
> > > > > annotation on the instance variable or on the the getter method of
> > > > > the class.
> > > > >
> > > > > It that true? Because I have an example where I receive a Null
> > > > > pointer exception if I put the annotation on the instance variable
> > > > > and not on the getter. Example below. The error occurs during the
> > > > > access of the JobList variable. The whole project is attached in
> > > > > case someone would like to have a look. For testing just exchange
> > > > > PersonNew.java with Person.java.
> > > > >
> > > > > Best regards, Lars
> > > > >
> > > > > ----------
> > > > >
> > > > > This works: ------------------------------
> > > > >
> > > > > package datamodel.impl;
> > > > >
> > > > > import java.util.ArrayList; import java.util.List;
> > > > >
> > > > > import javax.persistence.Column; import javax.persistence.Entity;
> > > > > import javax.persistence.GeneratedValue; import
> > > > > javax.persistence.GenerationType; import javax.persistence.Id;
> > import
> > > > > javax.persistence.OneToMany; import
> > > > > javax.persistence.OrderBy; import javax.persistence.Transient;
> > > > >
> > > > > import org.apache.openjpa.persistence.PersistentCollection;
> > > > >
> > > > > import datamodel.IPerson;
> > > > >
> > > > > @Entity public class PersonNew implements IPerson { private String
> > > > > id; private String firstName; private String lastName;
> > > > >
> > > > > private String nonsenseField = "";
> > > > >
> > > > > private List<Job> jobList = new ArrayList<Job>();
> > > > >
> > > > > private List<String> nickNameList = new ArrayList<String>();
> > > > >
> > > > > @Id @GeneratedValue(strategy=GenerationType.SEQUENCE) public
> String
> > > > > getId() { return id; }
> > > > >
> > > > > public void setId(String Id) { this.id = Id; }
> > > > >
> > > > >
> > > > > public String getFirstName() { return firstName; }
> > > > >
> > > > > public void setFirstName(String firstName) { this.firstName =
> > > > > firstName; }
> > > > >
> > > > > // Leave the standard column name of the table public String
> > > > > getLastName() { return lastName; }
> > > > >
> > > > > public void setLastName(String lastName) { this.lastName =
> > > > > lastName; }
> > > > >
> > > > > @Transient public String getNonsenseField() { return
> nonsenseField;
> > > > >  }
> > > > >
> > > > > public void setNonsenseField(String nonsenseField) {
> > > > > this.nonsenseField = nonsenseField; }
> > > > >
> > > > > @OneToMany public List<Job> getJobsList() { return this.jobList;
}
> > > > >
> > > > > public void setJobsList(List<Job> nickName) { this.jobList
=
> > > > > nickName; }
> > > > >
> > > > > @PersistentCollection @OrderBy public List<String>
> > > > > getNickNameList() { return nickNameList; }
> > > > >
> > > > > public void setNickNameList(List<String> nickNameString) {
> > > > > this.nickNameList = nickNameString; } }
> > > > >
> > > > >
> > > > > This results in an error:
> > > > >
> > > > > package datamodel.impl;
> > > > >
> > > > > import java.util.ArrayList; import java.util.List;
> > > > >
> > > > > import javax.persistence.Column; import javax.persistence.Entity;
> > > > > import javax.persistence.GeneratedValue; import
> > > > > javax.persistence.GenerationType; import javax.persistence.Id;
> > import
> > > > > javax.persistence.OneToMany; import
> > > > > javax.persistence.OrderBy; import javax.persistence.Transient;
> > > > >
> > > > > import org.apache.openjpa.persistence.PersistentCollection;
> > > > >
> > > > > import datamodel.IPerson;
> > > > >
> > > > > @Entity public class Person implements IPerson { @Id
> > > > > @GeneratedValue(strategy=GenerationType.SEQUENCE) private String
> > > > > id; private String firstName; private String lastName;
> > > > >
> > > > > @Transient private String nonsenseField = ""; @OneToMany private
> > > > > List<Job> jobList = new ArrayList<Job>(); @PersistentCollection
> > > > > @OrderBy private List<String> nickNameList = new
> > > > > ArrayList<String>();
> > > > >
> > > > >
> > > > > public String getId() { return id; }
> > > > >
> > > > > public void setId(String Id) { this.id = Id; }
> > > > >
> > > > >
> > > > > public String getFirstName() { return firstName; }
> > > > >
> > > > > public void setFirstName(String firstName) { this.firstName =
> > > > > firstName; }
> > > > >
> > > > > // Leave the standard column name of the table public String
> > > > > getLastName() { return lastName; }
> > > > >
> > > > > public void setLastName(String lastName) { this.lastName =
> > > > > lastName; }
> > > > >
> > > > > public String getNonsenseField() { return nonsenseField; }
> > > > >
> > > > > public void setNonsenseField(String nonsenseField) {
> > > > > this.nonsenseField = nonsenseField; }
> > > > >
> > > > >
> > > > > public List<Job> getJobsList() { return this.jobList; }
> > > > >
> > > > > public void setJobsList(List<Job> nickName) { this.jobList
=
> > > > > nickName; }
> > > > >
> > > > >
> > > > > public List<String> getNickNameList() { return nickNameList;
}
> > > > >
> > > > > public void setNickNameList(List<String> nickNameString) {
> > > > > this.nickNameList = nickNameString; } }
> > > > >
> > > > >
> > > >
> > >
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message