Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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) <[EMAIL PROTECTED]> 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 >> >> >> >> >> >> >> >>
Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
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 <[EMAIL PROTECTED]> 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) <[EMAIL PROTECTED]> 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 >> >> >>
Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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) <[EMAIL PROTECTED]> 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 >> >> > >> >> >> --
Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
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 <[EMAIL PROTECTED]> 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) <[EMAIL PROTECTED]> 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 >> >> >>
Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
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) <[EMAIL PROTECTED]> 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
Re: [jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
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) <[EMAIL PROTECTED]> 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
[jira] Resolved: (OPENJPA-43) update of a persistent field using a @Lob annotation is not being marked dirty
[ 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