You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@openjpa.apache.org by rpalache <ra...@oracle.com> on 2009/03/24 18:49:41 UTC

Evicting an embedded object.

Hi all,

I have a question regarding evicting an embedded object.

When I call an evict on a persistent non-transactional object and if I call isPersistent() before and after evict then both returns true.

When I do the same for an embedded object then I get false on the isPersistent() call after evict.

I did not find any documentation around evicting an embedded object.

The way I understand Evict is that it removes the object from cache but why is the persistence capability of the embedded object is removed and also why is it not consistent with a non-embedded object ?

Here is a sample code, lets say there is an Order object (@Entity) and comment object (@Embeddable) that is embedded inside Order.

The following returns true, true ( outside transaction boundaries):

System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord));
OpenJPAEntityManager.evict(ord);
System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord));

The following returns true, false ( outside transaction boundaries):

Comment ord_cmt = ord.getComment();
System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord_cmt));
OpenJPAEntityManager.evict(ord_cmt);
System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord_cmt));

Please let me know if you need a complete test case.

OpenJPA version: openjpa-1.1.0-r422266:657916

Regards,
Ravi.
-- 
View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2528068.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Fwd: Evicting an embedded object.

Posted by Christiaan <ch...@hotmail.com>.
Hi Craig,
it is probably the same case. I am using Kodo (which as you probably know
uses OpenJPA as a base library). I registered this issue with Oracle and
through their support I got in discussion with engineering whether this is a
bug or not. The original bug is actually that the statemanager is nullified,
whereas I still need to retrieve it after the evict. Maybe as a remark to
this, section 10.3 "pre-clear" is more specific about what should be
cleared:
"The method is called during any state transition to hollow. Non-persistent,
non-transactional fields should be cleared in this method. Associations
between this instance and others in the runtime environment should be
cleared."

then the hollow state itself (5.5.4):
"JDO instances that represent specific persistent data in the datastore but
whose values are not in the
JDO instance are hollow."

Is this intentional? Anyway, to avoid further discussion I proposed to
support to put the question on the jdo mailing list. Appearently,
engineering did the same on OpenJPA. (I actually registered the original
issue already in OPENJPA-453, back in 2007)

hope that clarifies it,
Christiaan


Craig L Russell wrote:
> 
> This sounds familiar...
> 
> Craig
> 
> Begin forwarded message:
> 
>> Hi all,
>>
>> I have a question regarding evicting an embedded object.
>>
>> When I call an evict on a persistent non-transactional object and if  
>> I call isPersistent() before and after evict then both returns true.
>>
>> When I do the same for an embedded object then I get false on the  
>> isPersistent() call after evict.
>>
>> I did not find any documentation around evicting an embedded object.
>>
>> The way I understand Evict is that it removes the object from cache  
>> but why is the persistence capability of the embedded object is  
>> removed and also why is it not consistent with a non-embedded object ?
>>
>> Here is a sample code, lets say there is an Order object (@Entity)  
>> and comment object (@Embeddable) that is embedded inside Order.
>>
>> The following returns true, true ( outside transaction boundaries):
>>
>> System.out.println("isPersistent:" +  
>> OpenJPAEntityManager.isPersistent(ord));
>> OpenJPAEntityManager.evict(ord);
>> System.out.println("isPersistent:" +  
>> OpenJPAEntityManager.isPersistent(ord));
>>
>> The following returns true, false ( outside transaction boundaries):
>>
>> Comment ord_cmt = ord.getComment();
>> System.out.println("isPersistent:" +  
>> OpenJPAEntityManager.isPersistent(ord_cmt));
>> OpenJPAEntityManager.evict(ord_cmt);
>> System.out.println("isPersistent:" +  
>> OpenJPAEntityManager.isPersistent(ord_cmt));
>>
>> Please let me know if you need a complete test case.
>>
>> OpenJPA version: openjpa-1.1.0-r422266:657916
>>
>> Regards,
>> Ravi.
>>
>>
>> -- 
>> View this message in context:
>> http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2544592.html
>> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>>
> 
> Craig L Russell
> Architect, Sun Java Enterprise System http://db.apache.org/jdo
> 408 276-5638 mailto:Craig.Russell@sun.com
> P.S. A good JDO? O, Gasp!
> 
> 
>  
> 

-- 
View this message in context: http://www.nabble.com/Fwd%3A-Evicting-an-embedded-object.-tp22751565p22755521.html
Sent from the JDO - Development mailing list archive at Nabble.com.


Fwd: Evicting an embedded object.

Posted by Craig L Russell <Cr...@Sun.COM>.
This sounds familiar...

Craig

Begin forwarded message:

> Hi all,
>
> I have a question regarding evicting an embedded object.
>
> When I call an evict on a persistent non-transactional object and if  
> I call isPersistent() before and after evict then both returns true.
>
> When I do the same for an embedded object then I get false on the  
> isPersistent() call after evict.
>
> I did not find any documentation around evicting an embedded object.
>
> The way I understand Evict is that it removes the object from cache  
> but why is the persistence capability of the embedded object is  
> removed and also why is it not consistent with a non-embedded object ?
>
> Here is a sample code, lets say there is an Order object (@Entity)  
> and comment object (@Embeddable) that is embedded inside Order.
>
> The following returns true, true ( outside transaction boundaries):
>
> System.out.println("isPersistent:" +  
> OpenJPAEntityManager.isPersistent(ord));
> OpenJPAEntityManager.evict(ord);
> System.out.println("isPersistent:" +  
> OpenJPAEntityManager.isPersistent(ord));
>
> The following returns true, false ( outside transaction boundaries):
>
> Comment ord_cmt = ord.getComment();
> System.out.println("isPersistent:" +  
> OpenJPAEntityManager.isPersistent(ord_cmt));
> OpenJPAEntityManager.evict(ord_cmt);
> System.out.println("isPersistent:" +  
> OpenJPAEntityManager.isPersistent(ord_cmt));
>
> Please let me know if you need a complete test case.
>
> OpenJPA version: openjpa-1.1.0-r422266:657916
>
> Regards,
> Ravi.
>
>
> -- 
> View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2544592.html
> Sent from the OpenJPA Users mailing list archive at Nabble.com.
>

Craig L Russell
Architect, Sun Java Enterprise System http://db.apache.org/jdo
408 276-5638 mailto:Craig.Russell@sun.com
P.S. A good JDO? O, Gasp!


Re: Eager fetching of PersistentCollection gives error (solution OPENJPA-1020)

Posted by Tedman Leung <te...@sfu.ca>.
I've created a bug OPENJPA-1020 
https://issues.apache.org/jira/browse/OPENJPA-1020

Attached are 2 patches, 
1) to patch the junit tests to show and test the bug
2) a fix for the bug

I hope some one approves / merges this. :)


On Thu, Apr 02, 2009 at 10:06:32AM -0700, Paul Copeland wrote:
> Some ORMs may return a different type when a persisted Collection is  
> re-loaded.  But if you modify the original Collection after a flush()  
> that could be problematic.  In any case the user needs to know what  
> behavior can be relied upon (specification).
>
> Per the JPA spec, Date, Time, Calendar, etc. are a special case of  
> mutable persistent fields, but only entities are required to be handled  
> in persistent Collections.  Apparently the OpenJPA @PersistentCollection  
> has no restrictions on the type of elements, mutable or immutable, that  
> Collections can contain.
>
> On 4/2/2009 7:49 AM, Tedman Leung wrote:
>> that is correct, if I leave out the fetch type, it defaults to lazy and 
>> it works fine (so long as the entity is in an attached state).
>>
>> The other observation I noticed is that accessing the collection does 
>> not actually materialise the variable. It returns the data while I'm in 
>> the transaction / while it's attached, but as soon as it is detached I 
>> no longer have access to the data even if it were previously accessed. 
>> This prevented me from hacking a work around with  @PostLoad and just 
>> calling collection.size() in it.
>>
>> As for your second question, my answer is, I don't know. However I know in
>> some other ORM's, in the past, they wrote their own wrappers around things
>> like Sets and Map's so they could track additions and removals to the set.
>> Since this pertains to primitives only, almost all persistable primitives
>> are immutable (that I can think of) so it would generally suffice for
>> catching modifications.
>>
>>
>> On Thu, Apr 02, 2009 at 07:26:38AM -0700, Paul Copeland wrote:
>>   
>>> Hi Ted -
>>>
>>> Just to clarify, have you tried this with FetchType.EAGER and with no 
>>>  FetchType specified and in those cases the problem does not happen?
>>>
>>> A more general observation is that the semantics of this OpenJPA   
>>> @PersistentCollection extension do not seem to be fully specified (is 
>>>  there a document that ties all the OpenJPA extensions together in a  
>>> cohesive specification?).  In this case the elements of the Set are 
>>> not  persistence capable objects, they cannot be enhanced, and they 
>>> do not  have Identity or version information.  So how would the 
>>> EntityManager  know if an element is added to, or removed from, the 
>>> Set, or if a member  of the Set has a field changed?  There is not 
>>> even a way to invoke  Persist or Remove on a member of the Set since 
>>> they are not Entity  objects.  Possibly the only reliable strategy 
>>> would be for the  EntityManager to always delete all the members of 
>>> the Set and re-insert  them every time the Set is loaded.  That could 
>>> be very expensive if the  Set is large or if there a large number of 
>>> these Set objects that are  frequently loaded.  Or does OpenJPA wrap 
>>> these non-entity persistent  elements into some kind of runtime 
>>> pseudo-Entity (also expensive and  might not resolve all of these 
>>> issues)?
>>>
>>> - Paul
>>>
>>>
>>> On 4/1/2009 5:49 PM, Tedman Leung wrote:
>>>     
>>>> So I have a more clear picture of this error now. Quite simply 
>>>> eager  fetching of a persistent collection of strings fails.
>>>>
>>>> as an example :
>>>>
>>>> 	@PersistentCollection(fetch=FetchType.EAGER)
>>>> 	private HashSet<String> testStrings=new HashSet<String>();
>>>>
>>>> Just create the entity, add a string to the collection, the merge / 
>>>>  persist it.
>>>>
>>>> Then clear the entityManager and any second level caches you have 
>>>> (or just stop the jvm), and load the entity back and I get 
>>>>
>>>> 	<openjpa-1.2.1-r752877:753278 nonfatal general error>   
>>>> 	org.apache.openjpa.persistence.PersistenceException: 
>>>> java.lang.String cannot be cast to 
>>>> org.apache.openjpa.enhance.PersistenceCapable
>>>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:875)
>>>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:769)
>>>> 		at org.apache.openjpa.kernel.DelegatingBroker.find(DelegatingBroker.java:183)
>>>> 		at org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java:452)
>>>> 		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> 		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>> 		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>> 		at java.lang.reflect.Method.invoke(Method.java:597)
>>>> 	...
>>>> 	Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
>>>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:408)
>>>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:380)
>>>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
>>>> 		at org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
>>>> 		at org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
>>>> 		at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
>>>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)
>>>>
>>>>  Note that you must not be reloading the entity from memory, i.e.
>>>> you must clear the entity manager and make sure the entity cache is
>>>> off, or restart the jvm. 
>>>>
>>>> If you don't turn the entity caches off, it will just give you
>>>> back what you peristed and it will look like it works.
>>>>
>>>> Anyone got any ideas on how to fix or work around this? I'd really  
>>>> prefer my entity detached but I want this data
>>>> fetched eagerly.
>>>>         
>>
>>   
>

-- 
                                                           Ted Leung
                                                           tedman@sfu.ca

I am what what the world has taught me to be.

Re: Eager fetching of PersistentCollection gives error

Posted by Paul Copeland <te...@jotobjects.com>.
Some ORMs may return a different type when a persisted Collection is 
re-loaded.  But if you modify the original Collection after a flush() 
that could be problematic.  In any case the user needs to know what 
behavior can be relied upon (specification).

Per the JPA spec, Date, Time, Calendar, etc. are a special case of 
mutable persistent fields, but only entities are required to be handled 
in persistent Collections.  Apparently the OpenJPA @PersistentCollection 
has no restrictions on the type of elements, mutable or immutable, that 
Collections can contain.

On 4/2/2009 7:49 AM, Tedman Leung wrote:
> that is correct, if I leave out the fetch type, it defaults to lazy and it 
> works fine (so long as the entity is in an attached state).
>
> The other observation I noticed is that accessing the collection does not 
> actually materialise the variable. It returns the data while I'm in the 
> transaction / while it's attached, but as soon as it is detached I no 
> longer have access to the data even if it were previously accessed. This 
> prevented me from hacking a work around with  @PostLoad and just calling 
> collection.size() in it.
>
> As for your second question, my answer is, I don't know. However I know in
> some other ORM's, in the past, they wrote their own wrappers around things
> like Sets and Map's so they could track additions and removals to the set.
> Since this pertains to primitives only, almost all persistable primitives
> are immutable (that I can think of) so it would generally suffice for
> catching modifications.
>
>
> On Thu, Apr 02, 2009 at 07:26:38AM -0700, Paul Copeland wrote:
>   
>> Hi Ted -
>>
>> Just to clarify, have you tried this with FetchType.EAGER and with no  
>> FetchType specified and in those cases the problem does not happen?
>>
>> A more general observation is that the semantics of this OpenJPA  
>> @PersistentCollection extension do not seem to be fully specified (is  
>> there a document that ties all the OpenJPA extensions together in a  
>> cohesive specification?).  In this case the elements of the Set are not  
>> persistence capable objects, they cannot be enhanced, and they do not  
>> have Identity or version information.  So how would the EntityManager  
>> know if an element is added to, or removed from, the Set, or if a member  
>> of the Set has a field changed?  There is not even a way to invoke  
>> Persist or Remove on a member of the Set since they are not Entity  
>> objects.  Possibly the only reliable strategy would be for the  
>> EntityManager to always delete all the members of the Set and re-insert  
>> them every time the Set is loaded.  That could be very expensive if the  
>> Set is large or if there a large number of these Set objects that are  
>> frequently loaded.  Or does OpenJPA wrap these non-entity persistent  
>> elements into some kind of runtime pseudo-Entity (also expensive and  
>> might not resolve all of these issues)?
>>
>> - Paul
>>
>>
>> On 4/1/2009 5:49 PM, Tedman Leung wrote:
>>     
>>> So I have a more clear picture of this error now. Quite simply eager  
>>> fetching of a persistent collection of strings fails.
>>>
>>> as an example :
>>>
>>> 	@PersistentCollection(fetch=FetchType.EAGER)
>>> 	private HashSet<String> testStrings=new HashSet<String>();
>>>
>>> Just create the entity, add a string to the collection, the merge /  
>>> persist it.
>>>
>>> Then clear the entityManager and any second level caches you have (or 
>>> just stop the jvm), and load the entity back and I get 
>>>
>>> 	<openjpa-1.2.1-r752877:753278 nonfatal general error>  
>>> 	org.apache.openjpa.persistence.PersistenceException: java.lang.String 
>>> cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
>>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:875)
>>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:769)
>>> 		at org.apache.openjpa.kernel.DelegatingBroker.find(DelegatingBroker.java:183)
>>> 		at org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java:452)
>>> 		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> 		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> 		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> 		at java.lang.reflect.Method.invoke(Method.java:597)
>>> 	...
>>> 	Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
>>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:408)
>>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:380)
>>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
>>> 		at org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
>>> 		at org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
>>> 		at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
>>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)
>>>
>>>  Note that you must not be reloading the entity from memory, i.e.
>>> you must clear the entity manager and make sure the entity cache is
>>> off, or restart the jvm. 
>>>
>>> If you don't turn the entity caches off, it will just give you
>>> back what you peristed and it will look like it works.
>>>
>>> Anyone got any ideas on how to fix or work around this? I'd really 
>>> prefer my entity detached but I want this data
>>> fetched eagerly.
>>>   
>>>       
>
>   


Re: Eager fetching of PersistentCollection gives error

Posted by Tedman Leung <te...@sfu.ca>.
that is correct, if I leave out the fetch type, it defaults to lazy and it 
works fine (so long as the entity is in an attached state).

The other observation I noticed is that accessing the collection does not 
actually materialise the variable. It returns the data while I'm in the 
transaction / while it's attached, but as soon as it is detached I no 
longer have access to the data even if it were previously accessed. This 
prevented me from hacking a work around with  @PostLoad and just calling 
collection.size() in it.

As for your second question, my answer is, I don't know. However I know in
some other ORM's, in the past, they wrote their own wrappers around things
like Sets and Map's so they could track additions and removals to the set.
Since this pertains to primitives only, almost all persistable primitives
are immutable (that I can think of) so it would generally suffice for
catching modifications.


On Thu, Apr 02, 2009 at 07:26:38AM -0700, Paul Copeland wrote:
> Hi Ted -
>
> Just to clarify, have you tried this with FetchType.EAGER and with no  
> FetchType specified and in those cases the problem does not happen?
>
> A more general observation is that the semantics of this OpenJPA  
> @PersistentCollection extension do not seem to be fully specified (is  
> there a document that ties all the OpenJPA extensions together in a  
> cohesive specification?).  In this case the elements of the Set are not  
> persistence capable objects, they cannot be enhanced, and they do not  
> have Identity or version information.  So how would the EntityManager  
> know if an element is added to, or removed from, the Set, or if a member  
> of the Set has a field changed?  There is not even a way to invoke  
> Persist or Remove on a member of the Set since they are not Entity  
> objects.  Possibly the only reliable strategy would be for the  
> EntityManager to always delete all the members of the Set and re-insert  
> them every time the Set is loaded.  That could be very expensive if the  
> Set is large or if there a large number of these Set objects that are  
> frequently loaded.  Or does OpenJPA wrap these non-entity persistent  
> elements into some kind of runtime pseudo-Entity (also expensive and  
> might not resolve all of these issues)?
>
> - Paul
>
>
> On 4/1/2009 5:49 PM, Tedman Leung wrote:
>> So I have a more clear picture of this error now. Quite simply eager  
>> fetching of a persistent collection of strings fails.
>>
>> as an example :
>>
>> 	@PersistentCollection(fetch=FetchType.EAGER)
>> 	private HashSet<String> testStrings=new HashSet<String>();
>>
>> Just create the entity, add a string to the collection, the merge /  
>> persist it.
>>
>> Then clear the entityManager and any second level caches you have (or 
>> just stop the jvm), and load the entity back and I get 
>>
>> 	<openjpa-1.2.1-r752877:753278 nonfatal general error>  
>> 	org.apache.openjpa.persistence.PersistenceException: java.lang.String 
>> cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:875)
>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:769)
>> 		at org.apache.openjpa.kernel.DelegatingBroker.find(DelegatingBroker.java:183)
>> 		at org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java:452)
>> 		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> 		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>> 		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>> 		at java.lang.reflect.Method.invoke(Method.java:597)
>> 	...
>> 	Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:408)
>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:380)
>> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
>> 		at org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
>> 		at org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
>> 		at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
>> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)
>>
>>  Note that you must not be reloading the entity from memory, i.e.
>> you must clear the entity manager and make sure the entity cache is
>> off, or restart the jvm. 
>>
>> If you don't turn the entity caches off, it will just give you
>> back what you peristed and it will look like it works.
>>
>> Anyone got any ideas on how to fix or work around this? I'd really 
>> prefer my entity detached but I want this data
>> fetched eagerly.
>>   
>

-- 
                                                           Ted Leung
                                                           tedman@sfu.ca

The most important words I've learned to say - "I don't know".

Re: Eager fetching of PersistentCollection gives error

Posted by Paul Copeland <te...@jotobjects.com>.
Hi Ted -

Just to clarify, have you tried this with FetchType.EAGER and with no 
FetchType specified and in those cases the problem does not happen?

A more general observation is that the semantics of this OpenJPA 
@PersistentCollection extension do not seem to be fully specified (is 
there a document that ties all the OpenJPA extensions together in a 
cohesive specification?).  In this case the elements of the Set are not 
persistence capable objects, they cannot be enhanced, and they do not 
have Identity or version information.  So how would the EntityManager 
know if an element is added to, or removed from, the Set, or if a member 
of the Set has a field changed?  There is not even a way to invoke 
Persist or Remove on a member of the Set since they are not Entity 
objects.  Possibly the only reliable strategy would be for the 
EntityManager to always delete all the members of the Set and re-insert 
them every time the Set is loaded.  That could be very expensive if the 
Set is large or if there a large number of these Set objects that are 
frequently loaded.  Or does OpenJPA wrap these non-entity persistent 
elements into some kind of runtime pseudo-Entity (also expensive and 
might not resolve all of these issues)?

- Paul


On 4/1/2009 5:49 PM, Tedman Leung wrote:
> So I have a more clear picture of this error now. Quite simply eager 
> fetching of a persistent collection of strings fails.
>
> as an example :
>
> 	@PersistentCollection(fetch=FetchType.EAGER)
> 	private HashSet<String> testStrings=new HashSet<String>();
>
> Just create the entity, add a string to the collection, the merge / 
> persist it.
>
> Then clear the entityManager and any second level caches you have (or just 
> stop the jvm), and load the entity back and I get 
>
> 	<openjpa-1.2.1-r752877:753278 nonfatal general error> 
> 	org.apache.openjpa.persistence.PersistenceException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:875)
> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:769)
> 		at org.apache.openjpa.kernel.DelegatingBroker.find(DelegatingBroker.java:183)
> 		at org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java:452)
> 		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> 		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> 		at java.lang.reflect.Method.invoke(Method.java:597)
> 	...
> 	Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:408)
> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:380)
> 		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
> 		at org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
> 		at org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
> 		at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
> 		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)
>
>  
> Note that you must not be reloading the entity from memory, i.e.
> you must clear the entity manager and make sure the entity cache is
> off, or restart the jvm. 
>
> If you don't turn the entity caches off, it will just give you
> back what you peristed and it will look like it works.
>
> Anyone got any ideas on how to fix or work around this? 
> I'd really prefer my entity detached but I want this data
> fetched eagerly.
>   


Eager fetching of PersistentCollection gives error

Posted by Tedman Leung <te...@sfu.ca>.
So I have a more clear picture of this error now. Quite simply eager 
fetching of a persistent collection of strings fails.

as an example :

	@PersistentCollection(fetch=FetchType.EAGER)
	private HashSet<String> testStrings=new HashSet<String>();

Just create the entity, add a string to the collection, the merge / 
persist it.

Then clear the entityManager and any second level caches you have (or just 
stop the jvm), and load the entity back and I get 

	<openjpa-1.2.1-r752877:753278 nonfatal general error> 
	org.apache.openjpa.persistence.PersistenceException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:875)
		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:769)
		at org.apache.openjpa.kernel.DelegatingBroker.find(DelegatingBroker.java:183)
		at org.apache.openjpa.persistence.EntityManagerImpl.find(EntityManagerImpl.java:452)
		at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
		at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
		at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
		at java.lang.reflect.Method.invoke(Method.java:597)
	...
	Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to org.apache.openjpa.enhance.PersistenceCapable
		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.setInverseRelation(JDBCStoreManager.java:408)
		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initializeState(JDBCStoreManager.java:380)
		at org.apache.openjpa.jdbc.kernel.JDBCStoreManager.initialize(JDBCStoreManager.java:278)
		at org.apache.openjpa.kernel.DelegatingStoreManager.initialize(DelegatingStoreManager.java:111)
		at org.apache.openjpa.kernel.ROPStoreManager.initialize(ROPStoreManager.java:57)
		at org.apache.openjpa.kernel.BrokerImpl.initialize(BrokerImpl.java:894)
		at org.apache.openjpa.kernel.BrokerImpl.find(BrokerImpl.java:852)

 
Note that you must not be reloading the entity from memory, i.e.
you must clear the entity manager and make sure the entity cache is
off, or restart the jvm. 

If you don't turn the entity caches off, it will just give you
back what you peristed and it will look like it works.

Anyone got any ideas on how to fix or work around this? 
I'd really prefer my entity detached but I want this data
fetched eagerly.
-- 
                                                           Ted Leung
                                                           tedman@sfu.ca

// /*
You know things are getting a little fishy when you're commenting out 
comments.
// */

Re: Evicting an embedded object.

Posted by Rick Curtis <cu...@gmail.com>.
With my vague understanding of what's going on here, it appears that you are asking the same question just in a different context. 

Unfortunately I don't have a good enough understanding of OpenJPA to decide how this should work. Maybe someone else wants to take a look at this one, and OPENJPA-453? I did some hacking and found a way to get the consistent behavior, but I'm not sure of the repercussions.

-Rick

Hi Rick,

Yes I commented on that post.

But then later realized that an embedded object's state can also be persistant.

Meaning, 

If you check this current post, before evict if I check embeddedObject.isPersistent() then it returned true.

But after evicting an embedded object the isPersistent() is false but for an entity object it is true.

I think the difference should not be there between an embedded object and an entity object.

Hope it clears the questions as to why I had to open this issue.
Please let me know if you have any questions.

Thanks,
Ravi.



-- 
View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2570956.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Evicting an embedded object.

Posted by rpalache <ra...@oracle.com>.
Hi Rick,

Yes I commented on that post.

But then later realized that an embedded object's state can also be persistant.

Meaning, 

If you check this current post, before evict if I check embeddedObject.isPersistent() then it returned true.

But after evicting an embedded object the isPersistent() is false but for an entity object it is true.

I think the difference should not be there between an embedded object and an entity object.

Hope it clears the questions as to why I had to open this issue.
Please let me know if you have any questions.

Thanks,
Ravi.


Ravi -
This looks similar to a known problem (See https://issues.apache.org/jira/browse/OPENJPA-453). I see you commented on this JIRA a few weeks back?

-Rick


Hi,

Thanks for looking into this.

Please find the attached test case.

openJPATestCase.zip 

A readme.txt file is in the zip that gives you details on how to run the testcase.

Please let me know if you need anything else.

Regards,
Ravi.




-- 
View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2559010.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Evicting an embedded object.

Posted by Rick Curtis <cu...@gmail.com>.
Ravi -
This looks similar to a known problem (See https://issues.apache.org/jira/browse/OPENJPA-453). I see you commented on this JIRA a few weeks back?

-Rick


Hi,

Thanks for looking into this.

Please find the attached test case.

openJPATestCase.zip 

A readme.txt file is in the zip that gives you details on how to run the testcase.

Please let me know if you need anything else.

Regards,
Ravi.


-- 
View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2558868.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Evicting an embedded object.

Posted by rpalache <ra...@oracle.com>.
Hi,

Thanks for looking into this.

Please find the attached test case.

openJPATestCase.zip 

A readme.txt file is in the zip that gives you details on how to run the testcase.

Please let me know if you need anything else.

Regards,
Ravi.
-- 
View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2551873.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.


Re: Evicting an embedded object.

Posted by Rick Curtis <cu...@gmail.com>.
Ravi -
Can we get a full testcase? 

Thanks,
Rick


Hi all,

I have a question regarding evicting an embedded object.

When I call an evict on a persistent non-transactional object and if I call isPersistent() before and after evict then both returns true.

When I do the same for an embedded object then I get false on the isPersistent() call after evict.

I did not find any documentation around evicting an embedded object.

The way I understand Evict is that it removes the object from cache but why is the persistence capability of the embedded object is removed and also why is it not consistent with a non-embedded object ?

Here is a sample code, lets say there is an Order object (@Entity) and comment object (@Embeddable) that is embedded inside Order.

The following returns true, true ( outside transaction boundaries):

System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord));
OpenJPAEntityManager.evict(ord);
System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord));

The following returns true, false ( outside transaction boundaries):

Comment ord_cmt = ord.getComment();
System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord_cmt));
OpenJPAEntityManager.evict(ord_cmt);
System.out.println("isPersistent:" + OpenJPAEntityManager.isPersistent(ord_cmt));

Please let me know if you need a complete test case.

OpenJPA version: openjpa-1.1.0-r422266:657916

Regards,
Ravi.


-- 
View this message in context: http://n2.nabble.com/Evicting-an-embedded-object.-tp2528068p2544592.html
Sent from the OpenJPA Users mailing list archive at Nabble.com.