Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-users] NullPointerException in PersistenceObjectAttributeAccessor

Thanks, and thanks for your patience with my spotty emails; lots of irons in the fire.

Best,
Laird

On Mon, Jan 10, 2011 at 2:29 PM, Tom Ware <tom.ware@xxxxxxxxxx> wrote:
Hi Laird,

 We have taken a look at your earlier exception and we think we've found a scenario where an EclipseLink bug could cause this issue.

 Basically, the idea is that your default cache will have some soft and weak references.  If you have an object that was in the cache, but one of those references has been garbage collected we can get the NPE you listed earlier. The issue only exists in our open EclipseLink 2.2 code stream - that will ship with GlassFish 3.1.  We are currently trying to create a recreation of the issue and a fix to get it into our 2.2 version.

 The exception below appears to be something different and appears to be related to a class you have mapped using inheritance.  When you have more details about that scenario, please pass them along.

-Tom

Laird Nelson wrote:
OK, now I'm getting another NullPointerException that is EclipseLink in nature again, but this time it's a different stack.

Before I go further, here's the version information:

Eclipse Persistence Services - 2.2.0.v20101209-r8662

And here's the stack.  Same query again; haven't re-enabled logging at the finest level:

Caused by: java.lang.NullPointerException
   at org.eclipse.persistence.internal.sessions.AbstractRecord.get(AbstractRecord.java:276)
   at org.eclipse.persistence.descriptors.InheritancePolicy.classFromRow(InheritancePolicy.java:336)
   at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:484)
   at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:455)
   at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:723)
   at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:743)
   at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:424)
   at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1080)
   at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:808)
   at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
   at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:384)
   at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1126)
   at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2904)
   at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1508)
   at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1490)
   at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1464)
   at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:484)
   at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:741)

Going to go turn on logging now.  :-)

Best,
Laird

On Mon, Jan 10, 2011 at 12:01 PM, Laird Nelson <ljnelson@xxxxxxxxx <mailto:ljnelson@xxxxxxxxx>> wrote:

   Absolutely plain vanilla JPA installation; haven't gotten far along
   enough in the application yet to tune caching.  So whatever your
   defaults are--that's what I'm using.

   Best,
   Laird


   On Mon, Jan 10, 2011 at 11:56 AM, Tom Ware <tom.ware@xxxxxxxxxx
   <mailto:tom.ware@xxxxxxxxxx>> wrote:

       Laird,

        Can you also provide information about how your persistence
       unit and Entity caching is setup.  What persistence unit
       properties are you using related to caching?  Do you have
       caching options in orm.xml files?  Are there caching annotations
       besides the ones in the source provided below?

       -Tom

       Christopher Delahunt wrote:

           Hi Laird,

           Can you catch the exception and try calling
           JPAHelper.getEntityManager(em).getServerSession().getIdentityMapAccessor().printIdentityMap(AnswerEntity.class)
           ?
           This will show what is in the shared cache for this class
           when the exception occurs.  Also, can you turn logging on to
           finest?  This will show the exact revision of EclipseLink
           being used (I'm not sure which was
           picked up by Glassfish 3.1b36), and the log might help track
           down how a null is getting into the cache though hopefully
           it is not needed.
           I believe it might be being nulled out due to garbage
           collection.  If that is the case, a workaround might be to
           increase the size of the cache used for that object
           (assuming you are using a softCacheWeakIdentityMap), switch
           to a fullidentitymap, or set it to
           be isolated.
           Best Regards,
           Chris

           On 10/01/2011 10:31 AM, Laird Nelson wrote:

               (Oh, /not/ a simple bug; my mistake in my earlier
               response.  Sorry; long day already and it's just begun.)

               I've included a snippet of the code that builds and runs
               the query.

               This use case is actually not necessarily all that
               strange.  Imagine if you will a survey application where
               multiple choice answers are stored in tables, each of
               which has a structure like all the others.  Let's say
               there's a table named HomelessShelters, and it has rows
               that name homeless shelters in the greater metro area.
                Each row has an ID ("7") and a text ("Pine Street Inn").

                From these identically structured tables we can build
               up a set of Answer entities.  An Answer entity is mapped
               like this:

               @Entity(name = "Answer")
               @IdClass(AnswerEntity.AnswerID.class)
               @Table(name = "Answer")
               public class AnswerEntity implements Answer {

                /**
                 * The {@link NamedAnswerSet} to which this {@link
               AnswerEntity}
                 * belongs.  This field may be {@code null} only at
               construction
                 * time.
                 */
                @JoinColumn(insertable = false, name = "ANSWERSETNAME",
               nullable = false, updatable = false) // name must be
               uppercase for portability
                @ManyToOne(fetch = FetchType.EAGER, optional = false,
               targetEntity = NamedAnswerSetEntity.class)
                @NotNull
                NamedAnswerSet answerSet;
                 /**
                 * The opaque and unique identifier for this {@link
               AnswerEntity}.
                 */
                @Column(name = "ID") // name must be uppercase for
               portability
                @Id
                private int id;

                @Column(name = "ANSWERSETNAME") // name must be
               uppercase for portability
                @Id
                @NotNull
                private String answerSetName;

                /**
                 * The text describing this {@link AnswerEntity}.  This
               field may be
                 * {@code null} only at construction time.
                 */
                @Basic(optional = false)
                @Column(length = 100, name = "TEXT", nullable = false)
               // name must be uppercase for portability
                @NotNull
                private String text;

                /**
                 * A comma and/or whitespace-delimited {@link String}
               of identifiers
                 * usually supplied by the {@link TableAnswerSetEntity}
               that built
                 * this {@link AnswerEntity}.  An {@link AnswerEntity} will
                 * typically sift through this {@link String} to see if
               its {@link
                 * #getID() ID} is contained in it.
                 *
                 * @see #isFreeResponsePermitted()
                 */
                @Column(name = "FREERESPONSEIDS", length = 255,
               updatable = false)
                private String freeResponseIds;

                /**
                 * A {@link Boolean} representing the result of combing
               through the
                 * {@link #freeResponseIds} field for our own {@link
               #getID() id}.
                 *
                 * @see #isFreeResponsePermitted()
                 */
                @Transient
                private Boolean freeResponsePermitted;

               }

               Logically all AnswerEntities belong to AnswerSets.  One
               kind of AnswerSet is one drawn from a table in the
               manner that I've described.  Others include constrained
               numeric AnswerSets; still others are defined more or
               less out of thin air and backed by Drools, the JBoss
               rules engine.  Short answer: build an AnswerEntity one
               way or another, and that's what you pick when you choose
               an answer to a multiple choice question.

               So this query is concerned with constructing
               AnswerEntities out of particular kinds of tables.

               Here is a snippet of code that builds and runs the
               query.  I have not yet sanitized the inputs; obviously I
               need to guard against SQL injection here in a way that
               normally, using garden variety PreparedStatements, I
               wouldn't.

               final String tableName = "HomelessShelters"; // real
               code obviously gets this from somewhere else
               final String answerSetName = this.getName(); // e.g.
               "HomelessSheltersAnswerSet"
               assert answerSetName != null;
               final String sql;
               final StringBuilder sb = new StringBuilder("SELECT t.%s
               AS ID, '%s' AS ANSWERSETNAME, t.%s AS TEXT, %s AS
               FREERESPONSEIDS FROM %s t");
               if (orderByColumnName != null) {
                sb.append(" ORDER BY %s");
                sql = String.format(sb.toString(),
               this.getIDColumnName(), answerSetName,
               this.getTextColumnName(), this.freeResponseIds == null ?
               "NULL" : String.format("\"%s\"", this.freeResponseIds),
               tableName, orderByColumnName);
               } else {
                sql = String.format(sb.toString(),
               this.getIDColumnName(), answerSetName,
               this.getTextColumnName(), this.freeResponseIds == null ?
               "NULL" : String.format("\"%s\"", this.freeResponseIds),
               tableName);
               }
               *final Query q = em.createNativeQuery(sql,
               AnswerEntity.class);*
               assert q != null;
               @SuppressWarnings("unchecked")
               final List<AnswerEntity> results = q.getResultList();
               assert results != null;
               for (final AnswerEntity a : results) {
                if (a != null) {
                  a.setAnswerSet(this);
                }
               }
               returnValue = new LinkedHashSet<AnswerEntity>(results);

               So nothing too odd going on here, I don't think, at
               least where the query is concerned.

               Best,
               Laird

               On Mon, Jan 10, 2011 at 9:53 AM, Tom Ware
               <tom.ware@xxxxxxxxxx <mailto:tom.ware@xxxxxxxxxx>
               <mailto:tom.ware@xxxxxxxxxx
               <mailto:tom.ware@xxxxxxxxxx>>> wrote:

                  You might want to look at how FreeResponse is mapped.
                What is the
                  @Id, is there a way a component of the @Id can be
               unexpectedly
                  made null by the user.

                  How is the query executed?  Is there a result set
               mapping?

                  -Tom

                  Laird Nelson wrote:

                      I noticed that too; simple bug; should have been
                      t.freeResponseIds.

                      The query itself is actually dynamic and the
               table name is
                      supplied at query build time.  The intent is to
               turn this
                      native query into a set of entities, which works
               fine.

                      (There is a set of tables in my application that
               are under the
                      control of the user; they all share these fields
               in common.
                       Through various gyrations of the app, the user
               can pick which
                      table to build normalized entities out of; this
               native query
                      gets assembled from the table name.  So a simple
               entity
                      mapping doesn't work, because the table name is
               not known at
                      compile/startup time.)

                      I'll keep an eye on this and see if I can narrow
               down what I
                      was doing when it happens again.  I cannot
               reproduce this in a
                      unit test (I've tried, believe me).

                      Best,
                      Laird

                      On Mon, Jan 10, 2011 at 9:39 AM, Tom Ware
               <tom.ware@xxxxxxxxxx <mailto:tom.ware@xxxxxxxxxx>
                      <mailto:tom.ware@xxxxxxxxxx
               <mailto:tom.ware@xxxxxxxxxx>>
               <mailto:tom.ware@xxxxxxxxxx <mailto:tom.ware@xxxxxxxxxx>

                      <mailto:tom.ware@xxxxxxxxxx
               <mailto:tom.ware@xxxxxxxxxx>>>> wrote:

                         This exception seems to occur when trying to
               set a value in
                      a null
                         object.  I am not sure what would cause
               EclipseLink to try
                      to do
                         that.  Can you provide any other information
               about what is
                      occuring?

                         I notice that your example query selects
               "freeResponseIds"
                      but does
                         not link it to anything else in your query.
               (i.e. you
                      select t.id <http://t.id> <http://t.id>
                         <http://t.id>, t.text with "t." but
               freeResponseIds without
                      the

                         "t.") What is the goal here?

                         -Tom

                         Laird Nelson wrote:

                             I have an application that runs a simple
               JPA native
                      query.  99
                             out of 100 times the query works fine.
                Then every now
                      and again
                             I get this:

                             Caused by: java.lang.NullPointerException
                                at
                                                   org.eclipse.persistence.internal.descriptors.PersistenceObjectAttributeAccessor.setAttributeValueInObject(PersistenceObjectAttributeAccessor.java:46)
                                at
                                                   org.eclipse.persistence.mappings.DatabaseMapping.setAttributeValueInObject(DatabaseMapping.java:1426)
                                at
                                                   org.eclipse.persistence.mappings.DatabaseMapping.readFromRowIntoObject(DatabaseMapping.java:1317)
                                at
                                                   org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoObject(ObjectBuilder.java:343)
                                at
                                                   org.eclipse.persistence.internal.descriptors.ObjectBuilder.refreshObjectIfRequired(ObjectBuilder.java:3333)
                                at
                                                   org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1495)
                                at
                                                   org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:559)
                                at
                                                   org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:496)
                                at
                                                   org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:455)
                                at
                                                   org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:723)
                                at
                                                   org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:743)
                                at
                                                   org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:424)
                                at
                                                   org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1080)
                                at
                                                   org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:808)
                                at
                                                   org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1040)
                                at
                                                   org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:384)
                                at
                                                   org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1126)
                                at
                                                   org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2904)
                                at
                                                   org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1508)
                                at
                                                   org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1490)
                                at
                                                   org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1464)
                                at
                                                   org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:484)
                                at
                                                   org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:741)

                             Once the query has failed in this manner,
               it will
                      continue to
                             fail until application restart.

                             I am using the EclipseLink version that is
               bundled with
                             Glassfish 3.1b36.

                             My query is SELECT t.id <http://t.id>
               <http://t.id> <http://t.id>
                      <http://t.id> AS ID,

                             'FreeResponse' AS ANSWERSETNAME, t.text AS
               TEXT,
                      freeResponseIds
                             AS FREERESPONSEIDS FROM FreeResponse t


                             What is EclipseLink trying to tell me here?

                             Thanks,
                             Laird


                                                   ------------------------------------------------------------------------

                                            _______________________________________________
                             eclipselink-users mailing list
                             eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>>>

                                            https://dev.eclipse.org/mailman/listinfo/eclipselink-users

                         _______________________________________________
                         eclipselink-users mailing list
                         eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>>>

                                        https://dev.eclipse.org/mailman/listinfo/eclipselink-users



                                     ------------------------------------------------------------------------

                      _______________________________________________
                      eclipselink-users mailing list
                      eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
                      <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>>
                                     https://dev.eclipse.org/mailman/listinfo/eclipselink-users

                  _______________________________________________
                  eclipselink-users mailing list
                  eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
               <mailto:eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>>
                                 https://dev.eclipse.org/mailman/listinfo/eclipselink-users


               ------------------------------------------------------------------------

               _______________________________________________
               eclipselink-users mailing list
               eclipselink-users@xxxxxxxxxxx
               <mailto:eclipselink-users@xxxxxxxxxxx>
               https://dev.eclipse.org/mailman/listinfo/eclipselink-users
               

           ------------------------------------------------------------------------

           _______________________________________________
           eclipselink-users mailing list
           eclipselink-users@xxxxxxxxxxx
           <mailto:eclipselink-users@xxxxxxxxxxx>
           https://dev.eclipse.org/mailman/listinfo/eclipselink-users

       _______________________________________________
       eclipselink-users mailing list
       eclipselink-users@xxxxxxxxxxx <mailto:eclipselink-users@xxxxxxxxxxx>
       https://dev.eclipse.org/mailman/listinfo/eclipselink-users




------------------------------------------------------------------------

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users
_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


Back to the top