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