[
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
|
"eclipselink.cache.shared.default"="false"
Will disable the shared cache.
tware wrote:
>
> Hi Mike,
>
> To get behavior more akin to what you expect, try using the persistence
> unit
> property:
>
> eclipselink.cache.shared.default=true
>
> This setting will cause entities to be cached in an isolated manner.
>
> -Tom
>
> Mike Traum wrote:
>> I think this whole issue boils down to the following statement in the
>> spec:
>> "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."
>>
>> This, then, relies on the definition of "in-memory". It seems that
>> eclipselink has included the cache in the scope of "in-memory". I
>> believe the intent of the statement is that the object maintained by the
>> app will not be modified by JPA, but not that a future query (or find)
>> will reflect the change. Consider an embedded in-memory database. If
>> this statement was interpreted in a strict manner, it would conflict
>> with the statement that the entity must be removed from the database.
>>
>> Aside from the above, the differential between the cache and database
>> certainly leads to counter-intuitive situations that I have previously
>> described.
>>
>> mike
>>
>> christopher delahunt wrote:
>>> Hello Samba,
>>>
>>> 1) yes, and it currently does. 2) Maybe. It depends on if A's
>>> collection of children was fetched previously or not. If it was not
>>> fetched yet (if its lazy), when it is fetched it goes to the database,
>>> otherwise, it is as it is in the cache
>>> 3) The developer should maintain all relationships because JPA allows
>>> providers to use a cache. There is no way to know that an object's
>>> lazy relationships have been prefetched or not, and if they have, then
>>> they have to be maintained
>>> 4) Yes. When you remove an entity, an application should remove all
>>> references to it from other entities.
>>> 5) I'm not sure how this could be automatically handled, but is a
>>> valid feature request. The provider cannot know if A is around in the
>>> cache or not, or even if A is the only object referencing B. Such a
>>> feature might be nice, but I dont know how it would affect performance
>>> positively.
>>> 6) As references to removed entities are supposed to be cleared up,
>>> extra existence checking on each relationship might impact performance
>>> significantly enough to reduce the value of a cache at all. It might
>>> be seen as excessive to avoid a problem that is already considered to
>>> be an application issue. The other issue that would then arise is
>>> what to do when a removed reference is discovered, and how to even
>>> tell that this non-existing object was a removed object and not
>>> something added by the user (EclipseLink allows read-only access to
>>> its shared cache).
>>> 7) I don't know what A.getChildren().get(0).getB() is meant to return,
>>> I assume get(0) would return a B object? EclipseLink returns the A
>>> object from the cache, so the collection of children would be as they
>>> were originally constructed.
>>> The problem is not that B is still cached after it is removed, but
>>> that other entities that are cached still reference the removed B.
>>> When these are brought into the context, B is in essence resurected,
>>> and I believe this problem in mind when the JPA spec stated "Note that
>>> it is the application that bears responsibility for maintaining the
>>> consistency of runtime relationships", but thats my opinion of course.
>>>
>>> Best Regards,
>>> Chris
>>>
>>>
>>> Samba wrote:
>>>> Excuse me Tom for intervening in the discussion, but I suppose what
>>>> Mike says is quite correct!
>>>>
>>>> 1. when em.remove(object-of-B); is called, shouldn't it remove that
>>>> entity instance from the cache as well?
>>>> 2. when A is fetched from a new transaction, shouldn't the
>>>> object-of-A.getChildren() be a fresh list of objects of B?
>>>> 3. So, where does the "developer maintaining the relationship" come
>>>> into picture?
>>>> 4. do you mean the developer should also remove the association
>>>> between A and B?
>>>> 5. I believe this should have been handled automatically with
>>>> @ManyToOne annotation on the child side of the relation ship
>>>> 6. It would be better if eclipselink checks for existence of the
>>>> enitiy before loading the relationship in case if the relation has
>>>> not been cleaned up.
>>>> 7. Further, it would interesting to see if the
>>>> A.getChildren().get(0).getB() is returning the complete details of
>>>> the object or just the priomary key of the object.
>>>> I suspect, it is only retuning the primary key and hence a bug in
>>>> the way eclipselink is constructing objects from references.
>>>>
>>>> Regards,
>>>> Samba
>>>>
>>>> On Tue, Sep 1, 2009 at 8:49 PM, Tom Ware <tom.ware@xxxxxxxxxx
>>>> <mailto:tom.ware@xxxxxxxxxx>> 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 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 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
>>>>
>>>> <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
>>>> <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
>>>> <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
>> _______________________________________________
>> 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
>
>
-----
http://wiki.eclipse.org/User:James.sutherland.oracle.com James Sutherland
http://www.eclipse.org/eclipselink/
EclipseLink , http://www.oracle.com/technology/products/ias/toplink/
TopLink
Wiki: http://wiki.eclipse.org/EclipseLink EclipseLink ,
http://wiki.oracle.com/page/TopLink TopLink
Forums: http://forums.oracle.com/forums/forum.jspa?forumID=48 TopLink ,
http://www.nabble.com/EclipseLink-f26430.html EclipseLink
Book: http://en.wikibooks.org/wiki/Java_Persistence Java Persistence
--
View this message in context: http://www.nabble.com/EntityManager.remove-does-not-remove-entity-from-cache-tp25228824p25277619.html
Sent from the EclipseLink - Users mailing list archive at Nabble.com.