【问题标题】:Why Hibernate 4.3.7.Final saveOrUpdate fires update after every insert ?为什么 Hibernate 4.3.7.Final saveOrUpdate 在每次插入后触发更新?
【发布时间】:2015-05-06 11:11:25
【问题描述】:

在早期版本的 Hibernate 中, saveorUpdate 会根据实体触发插入或更新查询。

但在休眠 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 层

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 应用上下文配置 :- 配置休眠会话工厂

<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 日志:-所以当我第一次运行 MessageLoggerDAOImpl 的 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=?

【问题讨论】:

    标签: spring-4 hibernate-4.x


    【解决方案1】:

    这不是错误。是我的错误。我在 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
        }
    } 
    

    不便之处敬请见谅

    【讨论】:

      猜你喜欢
      • 2017-04-03
      • 1970-01-01
      • 1970-01-01
      • 2011-12-06
      • 2021-03-08
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多