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

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



Back to the top