Hibernate will not persist data after save

Eric picture Eric · May 23, 2012 · Viewed 8k times · Source

Can someone explain why the "lastAccessed" date does not get saved to the database in this example and how I can get it to save to the DB? My understanding is that the do object is an attached object after the save() call and therefore all modifications should be persisted automatically.

Note: "myDate" is persisted correctly, so all other spring configuration seems to be correct.

@Transactional(readOnly = false)
public DateObject getOrCreateDateObject(Date myDate) {
    DateObject do = null;

    do = getCurrentDateObject();  // For my tests, this has been returning null

    if (do == null) {
        // create a new object
        do = new DateObject();
        do.setDate(myDate);
        sessionFactory.getCurrentSession().save(do);
    }

    // This does not persist to the database
    do.setLastAccessed(new Date());

    return do;
}

I have also tried some of the following combinations (and more) after the save() call. None of these work:

sessionFactory.getCurrentSession().merge(do);  // tried before and after do.setDate(d2)

sessionFactory.getCurrentSession().update(do);

sessionFactory.getCurrentSession().saveOrUpdate(do);

sessionFactory.getCurrentSession().flush();

DateObject doCopy = (DateObject)sessionFactory.getCurrentSession().load(DateObject.class, do.getId());
sessionFactory.getCurrentSession().merge(doCopy);
doCopy.setLastAccessed(new Date());

I'm hoping this is an easy answer that I'm just not seeing. Thank you for your help!

Edit #1 05/22/2012

As requested, here is the mapping for this entity, specified in src/main/resources/META-INF/dateobject.hbm.xml. I can see that the columns are created in the database using "SELECT * FROM dateObjects" in the mysql client. MY_DATE is populated correctly, but LAST_ACCESSED is set to NULL.

<class name="com.example.entity.DateObject" table="dateObjects">
    <id name="id" column="DATE_OBJECT_ID">
        <generator class="identity" />
    </id>
    <property name="date" type="date" column="MY_DATE" />
    <property name="lastAccessed" type="date" column="LAST_ACCESSED" />
</class>

Edit #2 05/24/2012

I have a working SSCCE at https://github.com/eschmidt/dateobject. The interesting thing is that the web client (calling localhost:8080/view/test) shows that lastAccessed is set correctly, but when I check the database with the MySQL client, it shows that lastAccessed is NULL. With this complete set of code, can anybody see why the database wouldn't update even though the method is marked @Transactional?

Answer

Ryan Stewart picture Ryan Stewart · May 23, 2012

If you're absolutely certain that after running that code, do.date is stored in the db and do.lastAccessed isn't, then your connection and transaction are obviously set up correctly. My first guess would be incorrect mappings, since that's the simplest solution. You don't happen to have an @Transient on the field, the getter, or the setter for lastAccessed, do you? (Assuming, of course, that you're using annotations to map your domain objects.)

If you could provide an SSCCE, I'll bet I or someone else can give you a definitive answer.

Update: It's hard trimming a full application down to the smallest possible code that demonstrates a problem. The upshot is that you'll likely find the answer while you're at it. I have lots of sample projects in github that might help guide you if you just need a few nudges in the right direction. basic-springmvc might be closest to what you're doing, but it uses annotations instead of xml for mappings. It's also a Spring MVC project. It's a lot simpler to start a Spring context manually in a main class than to worry about a whole servlet container and the multiple contexts that Spring MVC wants you to have. spring-method-caching, for one, has an example of doing that.

As for the mapping you posted, it looks fine, though it's been a long while since I touched an XML mapping. Are you using field or property access? That could possibly have a bearing on things. Also, are there any custom listeners or interceptors in the SessionFactory that might be twiddling with your objects?