我在我的应用程序中使用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无法更新它。谢谢你的时间。
答案 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;
}