Thank you Kevin. I could not get it to work with refresh() but did get it working with find(). However, it only worked after the object was first detached (either by setting autoDetach or detach()ing it). Refresh() didn't work even after detach(); entity=em.merge(); em.refresh(). In the end, I found all this to be far too inefficient and wildly counter-intuitive and decided to punt by setting the value myself with lifecycle hooks rather than leverage the database's capabilities.
My expectation was that a call to persist() (upon commit()) should leave the object and the datastore 100% consistent with each other. I don't know enough to say whether this is a bug in OpenJPA, the JPA spec or my expectations. Seems like there's a need for an @GeneratedField or something that applies to non-key fields -- something that says "you need to get the value from the datastore if the entity didn't provide it". I don't know. I suppose if you're asking the database to generate a value then you may be talking about a scenario where the user is done with the object once it's inserted. But if the expectation is that the user may do more work on the object that is later flushed to the datastore then it makes more sense for the application to set those values. OK, I guess I talked myself out of it although I have to say I feel better declaring a default value than having to code and annotate for it. :-) Thanks again. On Wed, 2011-10-12 at 15:19 -0500, Kevin Sutter wrote: > Hi Tim, > Since the database is providing the value, you will need to do an explicit > action to pull the values from the table. Try doing the em.refresh(entity) > after the commit call. The em.persist() invocation does not push anything > to the database until a flush() or commit() is performed. So, there would > be nothing to refresh from the database until the flush/commit is > performed. That should work for you. > > Another idea is to do an em.find(), but since you have the entity handy, you > should be able to get by with the refresh() call. > > HTH, > Kevin > > On Tue, Oct 11, 2011 at 8:05 PM, Tim Watts <t...@cliftonfarm.org> wrote: > > > Hello, > > > > I'm sure this problem comes down to me not fully groking the JPA way: > > Using OpenJPA (2.0.1), how do I get a call to persist() to automatically > > populate non-nullable, non-key fields whose values are generated by the > > database? Here are the particulars: > > > > DDL: > > modified timestamp not null default current_timestamp, > > > > Entity: > > @Temporal (TemporalType.TIMESTAMP) > > @Column (insertable=false, updatable=false) > > private Calendar modified; > > > > Relevant JPA Property: > > openjpa.AutoDetach=close,commit,nontx-read > > > > Databases: > > PostgreSQL 8.4, Derby 10.8 > > > > Test (which fails): > > ...{set fields, but not 'modified'}... > > et = em.getTransaction(); > > et.begin(); > > em.persist(entity); > > et.commit(); > > assertNotNull(entity.getModified()); > > > > A query on the table, of course, shows a value for modified. > > > > Some things I've tried that haven't worked: > > * Immediately after persist, entity.getModified(); > > * Immediately after persist, em.refresh(entity); > > > > On a possibly related note, I'm puzzled as to why I'm seeing the > > following message when I run my tests despite the fact that I'm running > > the enhancer on my domain classes via the openjpa-maven-plugin > > (codehaus): > > > > INFO [main] openjpa.Enhance - You have enabled runtime > > enhancement, but have not specified the set of persistent > > classes. ... > > > > I've inspected the .class file and it has a pcGetmodified among other > > things. So it looks like the classes are indeed getting enhanced. > > > > Any insights? Do I need a post processor to populate 'modified'? > > > > > >