在早期版本的Hibernate中,saveorUpdate会根据实体触发插入或更新查询。
但是在hibernate 4.3.7每次插入后都会触发更新查询。我看到插入和更新查询。
域对象
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="LOGGER")
public class MessageLogger extends BaseDomainObject implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Column(name = "CP")
private String cpId;
@Column(name = "ACTION")
private String action;
@Column(name = "REQUEST", columnDefinition="text" )
private String request;
@Column(name = "RESPONSE", columnDefinition="text" )
private String response;
@Column(name = "SEND_FROM")
private String sendFrom;
@Column(name = "SEND_TO")
private String sendTo;
public MessageLogger(){
}
public MessageLogger(String cpId,String action,String sendFrom,String sendTo,String request){
this.cpId = cpId;
this.action=action;
this.sendFrom=sendFrom;
this.sendTo=sendTo;
this.request=request;
}
public String getRequest() {
return request;
}
public void setRequest(String request) {
this.request = request;
}
public String getResponse() {
return response;
}
public String getSendFrom() {
return sendFrom;
}
public void setSendFrom(String sendFrom) {
this.sendFrom = sendFrom;
}
public String getSendTo() {
return sendTo;
}
public void setSendTo(String sendTo) {
this.sendTo = sendTo;
}
public void setResponse(String response) {
this.response = response;
}
public String getCpId() {
return cpId;
}
public void setCpId(String cpId) {
this.cpId = cpId;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
}
基础域对象
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
@MappedSuperclass
public abstract class BaseDomainObject implements LastModifiable,Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "ID")
private Long id;
@Version
@Column(name = "VERSION", columnDefinition = "int default 0")
private int version;
@Column(name = "CREATION_TIMESTAMP", nullable = false, insertable = false, updatable = false, columnDefinition = "timestamp default CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
private Date creationTimestamp;
@Column(name = "LAST_UPDATED_TIMESTAMP", columnDefinition = "datetime")
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdatedTimestamp;
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
public Date getCreationTimestamp() {
return creationTimestamp;
}
public void setCreationTimestamp(Date creationTimestamp) {
this.creationTimestamp = creationTimestamp;
}
public Date getLastUpdatedTimestamp() {
return lastUpdatedTimestamp;
}
public void setLastUpdatedTimestamp(Date lastUpdatedTimestamp) {
this.lastUpdatedTimestamp = lastUpdatedTimestamp;
}
public Long getId() {
return id;
}
}
DAO Layer
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
public class MessageLoggerDAOImpl
implements MessageLoggerDAO {
@Autowired
SessionFactory sessionFactory;
@Override
@Transactional
public MessageLogger createOrUpdate(MessageLogger messageLogger) {
Session s = sessionFactory.getCurrentSession();
s.saveOrUpdate(messageLogger);
return messageLogger;
}
}
Spring应用程序上下文配置: - 配置hibernate会话工厂
<tx:annotation-driven />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.my.server.domainobjects" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Log4j日志: - 当我第一次运行MessageLoggerDAOmpl的createOrUpdate方法插入MessageLogger实体时,我看到下面的两个查询
[05 Mar 2015 12:11:15:365] DEBUG SQL::logStatement:109 - insert into LOGGER (LAST_UPDATED_TIMESTAMP, VERSION, ACTION, CP, REQUEST, RESPONSE, SEND_FROM, SEND_TO) values (?, ?, ?, ?, ?, ?, ?, ?)
[05 Mar 2015 12:11:15:546] DEBUG SQL::logStatement:109 - update LOGGER set LAST_UPDATED_TIMESTAMP=?, VERSION=?, ACTION=?, CP=?, REQUEST=?, RESPONSE=?, SEND_FROM=?, SEND_TO=? where ID=? and VERSION=?
答案 0 :(得分:0)
它不是bug。我的错误。我在saveorUpdate上也有事件监听器,我也在其中保存对象。
@Component
public class SaveOrUpdateDateListener extends DefaultSaveOrUpdateEventListener {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void onSaveOrUpdate(SaveOrUpdateEvent event) {
if (event.getObject() instanceof LastModifiable) {
LastModifiable record = (LastModifiable) event.getObject();
record.setLastUpdatedTimestamp(new Date());
}
//super.onSaveOrUpdate(event); // remove this line solve my problem
}
}
很抱歉给您带来不便