[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [eclipselink-users] EntityManager.remove does not remove entity from cache
|
Bugzilla issue added:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=288288
I still think that the behavior is odd. Your previous references to the
spec clearly indicate that the entity must be removed from the database.
But, I'm not sure that Reference 1 states that can't from the cache. It
seems logical that the statement about "in-memory references" refer to
the object maintained by the application. But, I'm not sure that it's is
required that it refers to the cache. It simply seems odd that a
EntityManager.find on A will return the removed B, but a
EntityManager.find on the removed B will return null.
Thanks for your time, Tom.
mike
Tom Ware wrote:
There may be an enhancement request in there somewhere. Please feel
free to enter one.
At the moment the JPA specification requires that you maintain your
relationships and does not mandate any automatic relationship
maintenance by the provider.
-Tom
Mike Traum wrote:
Sure. Here's a snippet:
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("select a FROM A a");
List<A> as = q.getResultList();
em.clear();
em.close();
B b = as.get(0).getChildren().get(0);
System.out.println(b.getId()); // prints '2'
em = emf.createEntityManager();
em.getTransaction().begin();
B bm = em.merge(b);
em.remove(bm);
em.getTransaction().commit(); // successfully removes b with id
'2' from database
em.clear();
em.close();
em = emf.createEntityManager();
q = em.createQuery("select a FROM A a");
as = q.getResultList();
b = as.get(0).getChildren().get(0);
System.out.println(b.getId()); // prints '2'
boolean contains = em.contains(b);
System.out.println(contains); // prints 'true'
em.clear();
em.close();
mike
Tom Ware wrote:
I am not sure I follow. Can you provide a code sample?
Mike Traum wrote:
Tom,
I see where you're coming from. The spec references that you gave
do seem to support this behavior (unfortunate, but that's an issue
for a different list). But, I think you then run into other
conflicts with the spec. For example, contains on that the removed
entity will return true after retrieving it with the query.
Section 3.2.5
The contains method returns true:
• If the entity has been retrieved from the database, and has not
been removed or detached.
• If the entity instance is new, and the persist method has been
called on the entity or the persist
operation has been cascaded to it.
The contains method returns false:
• If the instance is detached.
• If the remove method has been called on the entity, or the remove
operation has been cascaded
to it.
• If the instance is new, and the persist method
mike
mike
Tom Ware wrote:
The spec references I have found are in section 3.2.3 of the JPA
1.0 specification:
Reference 1:
---
Bidirectional relationships between managed entities will be
persisted based on references held by the
owning side of the relationship. It is the developer’s
responsibility to keep the in-memory references
held on the owning side and those held on the inverse side
consistent with each other when they change.
---
Reference 2: (for flushing)
----
The semantics of the flush operation, applied to an entity X are
as follows:
<snip>
- If X is a removed entity, it is removed from the database. No
cascade options are relevant.
----
Is there something I am missing in the spec that you can point me to?
-Tom
Mike Traum wrote:
Maybe I've been defining my entities strangely, but if you define
a @OneToMany on A and then a @ManyToOne on B (pointing to A), the
schema generated by eclipselink will have the foreign key in B
pointing to A. So, this will not be enforced by the database. I
can drop in some code to illustrate if desired.
If the above is not funky, I think, by the JPA spec, the DB
delete should not occur. Otherwise, the relationship 'magic' will
occur between app restarts but not within app queries.
mike
Tom Ware wrote:
EclipseLink relies on your DB foreign-key-contstraints to
enforce this.
i.e. You should get a SQL exception on the remove if a
foreign-key-constraint exists for this relationship.
Mike Traum wrote:
Yes, I thought that might be the answer. But, the
implementation seems odd. JPA doesn't provide magic for this,
but it is deleted from the database, however the cache is
maintained in a stale state. It seems to me that either it
should not be deleted from the database or it should be removed
from the cache.
mike
Tom Ware wrote:
Hi Mike,
You need to sever the relationship between an A and a B
before you remove B. JPA does not provide any magic for this.
-Tom
Mike Traum wrote:
I have the following enitiy map:
A->B->C (where -> represents a OneToMany relationship)
If I do a EntityManager.remove on a B, a following Query
(select all) will still return that entity, even though it
has been removed from the database.
Any ideas on the proper way to handle this?
Here's some code illustrating the issue:
EntityManager em = emf.createEntityManager();
Query q = em.createQuery("select a FROM A a");
List<A> as = q.getResultList();
em.clear();
em.close();
System.out.println(as.get(0).getChildren().size()); //
output is 2
B b = as.get(0).getChildren().get(0);
em = emf.createEntityManager();
em.getTransaction().begin();
B bm = em.merge(b);
em.remove(bm);
em.getTransaction().commit(); // successfully removes B
and children from database
em.clear();
em.close();
em = emf.createEntityManager();
q = em.createQuery("select a FROM A a");
as = q.getResultList();
em.clear();
em.close();
System.out.println(as.get(0).getChildren().size()); //
output is 2
em = emf.createEntityManager();
q = em.createQuery("select a FROM A a");
((ReadAllQuery)((EJBQueryImpl)q).getDatabaseQuery()).refreshIdentityMapResult();
as = q.getResultList();
em.clear();
em.close();
System.out.println(as.get(0).getChildren().size()); //
output is 1
Thanks,
Mike
_______________________________________________
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
_______________________________________________
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
_______________________________________________
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
_______________________________________________
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
_______________________________________________
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