4

im trying to build a spring (3.1) & hibernate (3.6.10) web application and having a problem with the hibernate events. I implemented my own DefaultSaveOrUpdateEventListener for updating/creating a dateCreated and lastUpdated date which is called on every .saveOrUpdate() event. So far so good.

Shouldn't this listener be called also on .save() or .update() events? Or am i missing something here?

Listener:

public class SaveOrUpdateDateListener extends DefaultSaveOrUpdateEventListener {

    private static final long serialVersionUID = 1L;

    private static Logger log = Logger.getLogger(SaveOrUpdateDateListener.class);


    @Override
    public void onSaveOrUpdate(SaveOrUpdateEvent event) {
        log.debug("Entered onSaveOrUpdate()");

        if (event.getObject() instanceof BaseDomain) {
            BaseDomain record = (BaseDomain) event.getObject();

            record.setDateUpdated(new Date());

            if (record.getDateCreated() == null) {
                record.setDateCreated(new Date());
            }
        }

        super.onSaveOrUpdate(event);
    }
}

Hibernate config (partially):

<sesssion-factory>

<event type="save-update">
            <listener class="net.test.listener.hibernate.SaveOrUpdateDateListener"/>
            <listener class="org.hibernate.event.def.DefaultSaveOrUpdateEventListener"/>
        </event>    
</session-factory>

example dao methods (doesn't work):

@Autowired
private SessionFactory sessionFactory;


@Override
public void add(Registration registration) {
    sessionFactory.getCurrentSession().save(registration);
}

@Override
public void update(Registration registration) {
    sessionFactory.getCurrentSession().update(registration);
}

example dao methods (works):

@Autowired
private SessionFactory sessionFactory;


@Override
public void add(Registration registration) {
    sessionFactory.getCurrentSession().saveOrUpdate(registration);
}

@Override
public void update(Registration registration) {
    sessionFactory.getCurrentSession().saveOrUpdate(registration);
}



Edit

After i dedcided not to use saveOrUpdate in general i hopefully solved my problem with using a base class like the following:

@MappedSuperclass
public class BaseDomain {

    @Id
    @GeneratedValue
    protected Integer id;

    @Column(nullable=false)
    protected Timestamp dateCreated;

    @Column(updatable = false, insertable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp")
    @Generated(GenerationTime.ALWAYS)
    protected Timestamp dateUpdated;


    protected BaseDomain() {
        this.dateCreated = new Timestamp(System.currentTimeMillis());
    }

    public Integer getId() {
        return id;
    }

    protected void setId(Integer id) {
        this.id = id;
    }

    public Timestamp getDateCreated() {
        return dateCreated;
    }

    public Date getDateUpdated() {
        return dateUpdated;
    }
}

As the current_timestamp can be used only once per table (mysql restriction) i tried to build the dateCreated via constructor.

4

1 に答える 1

6

保存更新イベントは、saveOrUpdate を呼び出した結果としてのみ発生します。保存更新は、保存と更新のある種の組み合わせではありません。そしてsaveOrUpdate。

ドキュメントでは、これは次のように綴られています。

14.2. イベント システム
...
セッション インターフェイスのすべてのメソッドは、イベントに関連付けられます。
...
これらのメソッドのいずれかでリクエストが行われると、Hibernate セッションは適切なイベントを生成し、そのタイプの構成済みイベント リスナーに渡します。

于 2012-06-18T19:09:07.013 に答える