openjpa-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Prud'hommeaux <mprud...@apache.org>
Subject Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
Date Thu, 14 Sep 2006 22:32:15 GMT
David-

Well, the problem is that you aren't assigning the field to a new  
value, and what you are changing isn't a detectably mutable value of  
a persistent field. I can't definitively say if this makes us non- 
spec-compliant or not in terms of the letter of the spec, but  
consider the alternative: since the Lob annotation is basically  
saying that the instance is an opaque blob of serializable bytes, we  
don't know anything about it, we don't mediate field access, and we  
never mark it dirty. So if we were to guarantee that changed Lobs are  
always updated at commit time, we'd need to do one of the following:

    1. Write the current value of the Lob field on commit for every  
instance that was obtained in the transaction (which could mean  
potentially thousands of unnecessary updates)

    2. Manually compare the serialized bytes of every single Lob  
field upon commit, which would be faster than #1, but still  
prohibitively slow

If you have any suggestions on how to get around this problem, please  
let us know.


On a separate track, considering that your Lob of type Address sounds  
a lot like a persistent entity itself, are you sure you wouldn't  
rather be declaring it @Embedded and storing it in individual columns  
of the owning table? As well as allowing it to be queried, you would  
also have automatic dirty tracking as you expect, and you wouldn't  
need to store it as an opaque blob of serialized bytes.



On Sep 14, 2006, at 3:11 PM, David Wisneski wrote:

> I would think that this would have to be fixed in order to comply  
> with JPA
> spec.
> The JPA spec section 3.2.3 says that updates to persistent entities  
> are
> written
> back to the database during synchronization and "An update to the  
> state of
> an entity includes both the assignment of a new value to a persistent
> property
> or field of the entity as well as the modification of a mutable  
> value of a
> persistent
> property or field."   There is not to my knowledge any requirement  
> in JPA
> that a
> value has to be set null first.
>
>
> On 9/14/06, Marc Prud'hommeaux <mprudhom@apache.org> wrote:
>>
>>
>> We might just be being too clever here ... if a field is set, but
>> oldvalue==newvalue, then we don't mark it dirty. That obviously
>> breaks down for cases like this, where we can't perform dirty
>> tracking on the opaque blob.
>>
>> You might need to resign yourself to either having an intermediate
>> null setting, or else manually calling OpenJPAEntityManager.dirty()
>> on the field to make sure the system knows that it has changed. You
>> can always make your setter perform the additional intermediate null
>> setting.
>>
>>
>>
>>
>> On Sep 14, 2006, at 12:29 PM, David Wisneski wrote:
>>
>> > that works.
>> >    Address a = e.getHome();
>> >    a.setCity("NewCity");
>> >    e.setHome(null);
>> >    e.setHome(a);
>> >
>> > Also if I create a new instance of Address as in
>> >   Address newa = new Address("....");
>> >    e.setAddress(newa);
>> >
>> > Both of the above work.
>> >
>> > But doing an update with making a new copy of the Adresss does not
>> > work for
>> > me.
>> >   e.setHome( e.getHome().setCity("NEW"));
>> >
>> > Do I have to override equals on the Address ?
>> >
>> >
>> > On 9/14/06, Marc Prud'hommeaux <mprudhom@apache.org> wrote:
>> >>
>> >> David-
>> >>
>> >> > There was a typo in my code.  But even doing this, the update is
>> >> > not being
>> >> > written back to the database at commit or flush.
>> >>
>> >> That's a little surprising.
>> >>
>> >> What happens if you do this:
>> >>
>> >> Blob home = e.getHome();
>> >> home.setStreet("new value");
>> >> e.setHome(null);
>> >> e.setHome(home);
>> >>
>> >>
>> >>
>> >>
>> >> On Sep 14, 2006, at 11:31 AM, David Wisneski wrote:
>> >>
>> >> > I think I am doing what you suggest.  After changing the  
>> value of
>> >> > home the
>> >> > program does
>> >> >  e.setHome( e.getHome().setStreet(" new value"));
>> >> >
>> >> > There was a typo in my code.  But even doing this, the update is
>> >> > not being
>> >> > written back to the database at commit or flush.
>> >> >
>> >> >
>> >> > On 9/10/06, Marc Prud'hommeaux (JIRA) <jira@apache.org> wrote:
>> >> >>
>> >> >>     [ http://issues.apache.org/jira/browse/OPENJPA-43? 
>> page=all ]
>> >> >>
>> >> >> Marc Prud'hommeaux resolved OPENJPA-43.
>> >> >> ---------------------------------------
>> >> >>
>> >> >>    Resolution: Invalid
>> >> >>
>> >> >> This is actually a known and intractible limitation: we are not
>> >> >> able to
>> >> >> intercept internal modifications for opaque types or arrays. So
>> >> >> for those
>> >> >> types, if OpenJPA is to detect that they were changed, they  
>> need
>> >> >> to be
>> >> >> re-set in their owning objects. E.g., in addition to doing:
>> >> >>
>> >> >> myPC.getSomeBlob().someInternalField++;
>> >> >>
>> >> >> you should also do:
>> >> >>
>> >> >> myPC.setSomeBlob(myPC.getSomeBlob());
>> >> >>
>> >> >> That should be sufficient to mary it "dirty". Alternately,  
>> you can
>> >> >> use the
>> >> >> OpenJPAEntityManager.dirty() method to explicitly mark the  
>> field
>> >> >> dirty.
>> >> >>
>> >> >> > update of a persistent field using a @Lob annotation is not
>> >> >> being marked
>> >> >> dirty
>> >> >> >
>> >> >>
>> >>  
>> ---------------------------------------------------------------------
>> >> >> ---------
>> >> >> >
>> >> >> >                 Key: OPENJPA-43
>> >> >> >                 URL: http://issues.apache.org/jira/browse/
>> >> >> OPENJPA-43
>> >> >> >             Project: OpenJPA
>> >> >> >          Issue Type: Bug
>> >> >> >          Components: kernel
>> >> >> >            Reporter: David Wisneski
>> >> >> >
>> >> >> > An entity has a persistent field which is a serialable class
>> >> >> annotated
>> >> >> with @Lob.  I am able to
>> >> >> > create and persist instances of this entity and field.   
>> But when
>> >> >> the
>> >> >> entity is retrieved and the
>> >> >> > field is updated, the update is not written back at commit.
>> >> >> > @Entity
>> >> >> >  class Employee {
>> >> >> >   @Id  int id;
>> >> >> >   @Lob  Address home;
>> >> >> > class Home implements Serializable {
>> >> >> >     String street
>> >> >> >   EntityManager em =
>> >> >> >   em.getTransaction().begin();
>> >> >> >   Employee e = em.find(Employee.class, 1);
>> >> >> >   Address home = e.getHome();
>> >> >> >   home.setStreet("123 New Avenue");
>> >> >> >   e.setHome(e);
>> >> >> >   em.getTransaction().commit();   <--  the update to home
>> >> >> address does
>> >> >> not occur.
>> >> >>
>> >> >> --
>> >> >> This message is automatically generated by JIRA.
>> >> >> -
>> >> >> If you think it was sent incorrectly contact one of the
>> >> >> administrators:
>> >> >> http://issues.apache.org/jira/secure/Administrators.jspa
>> >> >> -
>> >> >> For more information on JIRA, see: http://www.atlassian.com/
>> >> >> software/jira
>> >> >>
>> >> >>
>> >> >>
>> >>
>> >>
>>
>>


Mime
View raw message