Skip to main content

[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

Tom / James,

I'm confused here; should we use true or false for this property?

what is the effect of the shared cache on the problem at hand?

And what is the effect of disabling the shared cache? 
do we completely lose the benefits of the cache? 
Or what will be the net gain or loss in terms of performance  because of using this setting for this purpose?

Thanks and Regards,
Samba

On Thu, Sep 3, 2009 at 8:14 PM, James Sutherland <jamesssss@xxxxxxxxx> wrote:

"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.

_______________________________________________
eclipselink-users mailing list
eclipselink-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/eclipselink-users


Back to the top