TIMESTAMP列未更新

时间:2011-09-14 08:26:02

标签: mysql hibernate

我在我的应用程序中使用Struts2,Spring和Hibernate,数据库是MySQL 5.5。我在数据库中有这个表:

create table if not exists campaigns(
    id int(10) not null auto_increment,
    campaignId int(25) not null unique,
    createdBy int(25) not null REFERENCES users(userId),
    campaignName varchar(255) not null,
    subject varchar(500),
    body varchar(50000),
    modifiedOn TIMESTAMP,
    triggeredOn date,
    numberOfTargets int(10),
    primary key (id, campaignId)
);

我使用以下方法保存并更新“Campaign”对象(通过hbm文件进行hibernate-mapping):

public boolean addCampaign(long createdBy, String campaignName) throws NoSuchAlgorithmException {
    Campaign campaignObject = new Campaign();
    SecureRandom generatedHash = SecureRandom.getInstance("SHA1PRNG");
    campaignObject.setCampaignId(new Integer(generatedHash.nextInt()));
    campaignObject.setCreatedBy(createdBy);
    campaignObject.setCampaignName(campaignName);
    getHibernateTemplate().save(campaignObject);
    getSession().flush();
    return true;
}

public Date updateCampaign(String campaignId, String subject, String body) throws NumberFormatException {
    Campaign campaign = getCampaignByCampaignId(Long.parseLong(campaignId));
    if(campaign != null) {
        campaign.setSubject(subject);
        campaign.setBody(body);
        getHibernateTemplate().save(campaign);
        getSession().flush();
        return campaign.getModifiedOn();
    }
    return null;
}

当我在数据库上运行更新查询时,“modifiedOn”列会更新。但是hibernate无法更新它。谢谢你的时间。

2 个答案:

答案 0 :(得分:5)

首先,save用于插入新实体。更新附加实体时不应使用它。附加实体的状态在刷新时自动写入数据库(如果已更改)。你不需要调用任何东西来更新状态。

Hibernate不会神奇地重新读取它已插入/更新的行以获取生成的时间戳。这样做需要特定的@Generated注释。但它会降低应用程序的性能。

我会使用pre-insert / pre-update挂钩以编程方式在实体中设置modifiedOn值,并避免在数据库中自动修改时间戳。

答案 1 :(得分:1)

除了JB Nizet's response之外,如果触发器正在更新modifiedOn,请查看org.hibernate.Session#refresh()

如果字段由触发器更新,当hibernate保存实体时它具有旧日期,触发器在数据库级别(而不是休眠实体)上更新记录,然后在会话关闭时,在提交时, Hibernate将实体视为脏,因为modifiedOn字段在DB中具有不同的值。因此,启动另一个更新,就好像触发器永远不会更新字段。 refresh()将在更新后使用DB中的实体状态更新实体的状态,以及触发器执行,因此它们可以在提交时同步。

public Date updateCampaign(String campaignId, String subject, String body) 
        throws NumberFormatException {
    Campaign campaign = getCampaignByCampaignId(Long.parseLong(campaignId));
    if(campaign != null) {
        campaign.setSubject(subject);
        campaign.setBody(body);
        getHibernateTemplate().update(campaign);
        getSession().flush();
        getSession.refresh(campaign);
        return campaign.getModifiedOn();
    }
return null;
}