dev@glassfish.java.net

Re: TopLink: Data retrieval after EM closed, bug?

From: Tom Ware <tom.ware_at_oracle.com>
Date: Thu, 28 Aug 2008 09:18:31 -0400

Hi Antonio,

   It's funny how people run into the same issues at the same times. There was
a similar post on the GlassFish dev list on Tuesday entitled, "sth doubt about
detached entity".

   Basically here is the idea.

   When you close your entity manager, your entities go into the detached state.
  The JPA specification tells you what operations you can rely on working with
entities in the detached state regardless of what persistence provider you use.
   It is not specific about what should happen to lazy relationships after an
EntityManager is closed. It just says that you cannot rely on being able to
trigger them.

   TopLink Essentials and EclipseLink have chosen to allow you to trigger those
lazy relationships if the database connection is available even after the
EntityManager is closed. We believe that provides more useful functionality
that disallowing triggering those relationships.

-Tom

Antonio Sánchez wrote:
> Hello.
>
> I think TopLink is retrieving data after EM has been closed in the case
> below, and I'm not sure if this behavior is correct.
>
> CASE: (Steps 1 to 4 and follows)
>
> STEP 1.- I'm using a recursive table (most probably the same applies for
> non-recursive tables):
>
> create table "SA"."RECURSIVA" (
> PK int primary key not null,
> DATO varchar(10),
> PADRE int references RECURSIVA
> );
>
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (0,'Raiz',null);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (1,'n1',0);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (2,'n2',1);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (3,'n3',2);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (4,'n4',3);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (5,'n5',4);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (6,'n6',5);
> INSERT INTO "SA"."RECURSIVA" (PK,DATO,PADRE) VALUES (7,'n7',6);
>
> STEP 2.- This is the entity (note the LAZY fetch type):
>
> @Entity
> @Table(name = "RECURSIVA")
> public class Recursiva implements Serializable {
> @Id
> @Column(name = "PK", nullable = false)
> private Integer pk;
> @Column(name = "DATO")
> private String dato;
> @OneToMany(mappedBy = "padre")
> private Collection<Recursiva> recursivaCollection;
> @JoinColumn(name = "PADRE", referencedColumnName = "PK")
> @ManyToOne(fetch=FetchType.LAZY)
> private Recursiva padre;
> ....
>
> STEP 3.- This is the data retrieval code (note EntityManager is closed
> before accesing data):
>
> EntityManagerFactory emf =
> Persistence.createEntityManagerFactory("mijpa");;
> EntityManager em = emf.createEntityManager();
> Recursiva rc = null;
>
> rc = em.find(Recursiva.class, 7);
> em.close();
>
> while (rc != null) {
> System.out.println(rc.getDato());
> rc = rc.getPadre();
> }
>
> emf.close();
>
> STEP 4.- Results:
>
> n7
> n6
> n5
> n4
> n3
> n2
> n1
> Raiz
>
> QUESTIONS: If em is closed right after the leaf entity is retrieved:
>
> A. How is it possible that all of the leaf ancestors up to the root are
> retrieved?
> B. Is toplink accessing the database after em is closed or simply the
> full hierarchy is eagerly loaded at the very beginning?
> C. Is this correct, or is it a bug?
>
> NOTE: openjpa prints n7 and n6, as I would have expected.
>
> I would appreciate your comments, specially if you think this is a bug,
> in order to report it.
>
> Thank you and regards.
> Antonio.
>
> Tested with:
> * [Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))]
> * [derby 10.4.1.3]
> * [java hotspot 1.6.0_06-b02]
> * [ubuntu 8.04.1 2.6.24-19-generic]
>
>