I've decided to file a bug report. I can't speak for the JPA 2.0
specification, but the behavior of OpenJPA is clearly inconsistent. I've
attached a more complete description of the problem below.
FWIW, this surprised me in production after having passed all my unit tests.
The unit tests assumed an empty database and therefore created the entities
before persisting them. This caused the entities to be placed in cache.
Subsequent attempts to load each entity then returned the full object. In
production, however, the cache starts off empty and the 'getSingleResult' call
only loads part of the entity. Using an 'em.find' as a workaround then causes
the complete entity to be loaded into the cache. Any subsequent calls to
'getSingleResult' will then return the entire entity.
-=- Jerry
P.S. I attempted to follow the call stack down for each path but ended up quite
lost. *sigh* Tried.
[A.java]
@Entity
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="class_type",
discriminatorType=DiscriminatorType.INTEGER)
public abstract class A {
// Defines an ID and at least one persistent field.
}
[B.java]
@Entity
@DiscriminatorValue("2")
class B extends A implements Serializable {
...
private String details;
public String getDetails() { return details; }
public void setDetails(String details) { this.details = details; }
...
}
[SomeDAOImpl.java]
TypedQuery<A> query = em.createNamedQuery("GetDetails", A.class);
A a = query.getSingleResult();
Assert.assertTrue(a instanceof B);
Assert.assertNull(a.getDetails()); // ERROR: This should be defined
em.refresh(a);
Assert.assertTrue(a instanceof B);
Assert.assertNull(a.getDetails()); // ERROR: This should be defined
a = em.merge(a);
Assert.assertTrue(a instanceof B);
Assert.assertNull(a.getDetails()); // ERROR: This should be defined
a = em.find(A.class, a.getId());
Assert.assertTrue(a instanceof B);
Assert.assertNotNull(a.getDetails()); // SUCCESS!
a = query.getSingleResult();
Assert.assertTrue(a instanceof B);
Assert.assertNotNull(a.getDetails()); // SUCCESS!
On Nov 12, 2010, at 8:23 AM, Rick Curtis [via OpenJPA] wrote:
> Jerry -
>
> Maybe you omitted something when you wrote your email... but does class B
> have an @Entity annotation?
>
> ... I figured we could start with the obvious. :-)
>
> Thanks,
> Rick
>
> On Thu, Nov 11, 2010 at 11:49 PM, Jerry Carter <[hidden email]>wrote:
>
> > In OpenJPA 2.0.1, I define a native query which returns the base class for
> > a group of inherited classes.
> >
> > Query query = em.createNativeQuery("...", A.class);
> >
> > The inherited classes are simple and have the form:
> >
> > @Entity
> > @Inheritance(strategy=InheritanceType.JOINED)
> > @DiscriminatorColumn(name="class_type",
> > discriminatorType=DiscriminatorType.INTEGER)
> > public abstract class A {
> > // Defines an ID and at least one persistent field.
> > }
> >
> > class B extends A implements Serializable {
> > ...
> > private String details;
> > public String getDetails() { return details; }
> > public void setDetails(String details) { this.details =
> > details; }
> > ...
> > }
> >
> > My expectation is that this query should return an instance of B with any
> > new fields resolved automatically (i.e. details should be non-NULL).
> > Instead I am getting an instance of B but with only the fields defined by
> > A
> > being initialized! Am I crazy or is something broken?
> >
> > -=- Jerry
>
>
> View message @
> http://openjpa.208410.n2.nabble.com/Do-native-queries-respect-inheritance-tp5731353p5732314.html
>
> To start a new topic under OpenJPA Users, email
> [email protected]
> To unsubscribe from OpenJPA Users, click here.
>
--
View this message in context:
http://openjpa.208410.n2.nabble.com/Do-native-queries-respect-inheritance-tp5731353p5733108.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.