openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tedman Leung <ted...@sfu.ca>
Subject Re: Eager fetching of PersistentCollection gives error
Date Thu, 02 Apr 2009 14:49:58 GMT
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".

Mime
View raw message