我們強烈建議您使用一些事件偵聽器調用publisher.sendObjectAddedMessage()
。
即你應該創建一個偵聽器,在任何對象被持久化之後調用一個方法,以確保你的sendObjectAddedMessage()
在實體持久化之前不會被調用。
考慮這個例子:
我會堅持這個簡單的實體Person.java
,我將幾個事件與此類關聯。無論何時保存此實體,都會在負責此實體的事務處理之前和之後調用一些方法。
Person.java
@Entity
public class Person implements Serializable {
@Id
@GeneratedValue (strategy = GenerationType.AUTO)
int id;
String name;
//getters and setters below this
...
}
現在考慮我的Main
類。你可以看到我創建了AuditLogInterceptor
並將它與會話相關聯。
通過將此攔截器與會話相關聯,它將調用攔截器的幾種方法,如onSave
,preFlush
和postFlush
方法。這將確保在需要時總是調用這些方法。 (如postFlush
不會被保存實體之前調用)
Test.java
public class Test {
public static void main(String[] args) {
AuditLogInterceptor interceptor = new AuditLogInterceptor();
Session session = HibernateUtil.getSessionFactory()
.withOptions()
.interceptor(interceptor)
.openSession();
interceptor.setSession(session);
Person p = new Person();
p.setName("John Doe");
session.getTransaction().begin();
session.save(p);
session.getTransaction().commit();
session.close();
}
}
這是主類AuditLogInterceptor.java
的代碼。它實現了休眠的EmptyInterceptor
接口。正如您在Test.java
中所瞭解的那樣,我們將會話與此攔截器關聯。因此,它的覆蓋方法將被稱爲在幾個事件,如保存,更新等..
AuditLogInterceptor.java
package test;
import java.io.Serializable;
import java.util.Iterator;
import org.hibernate.CallbackException;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Session;
import org.hibernate.type.Type;
public class AuditLogInterceptor extends EmptyInterceptor{
Session session;
public void setSession(Session session) {
this.session=session;
}
@Override
public boolean onSave(Object entity,Serializable id,
Object[] state,String[] propertyNames,Type[] types)
throws CallbackException {
System.out.println("onSave");
return false;
}
//called before commit into database
@Override
public void preFlush(Iterator iterator) {
System.out.println("preFlush");
}
//called after committed into database
@Override
public void postFlush(Iterator iterator) {
System.out.println("postFlush");
}
}
現在
Hibernate: drop table if exists hibernate_sequence
Hibernate: drop table if exists Person
Hibernate: create table hibernate_sequence (next_val bigint)
Hibernate: insert into hibernate_sequence values (1)
Hibernate: create table Person (id integer not null, name varchar(255), primary key (id))
Feb 16, 2016 8:23:18 AM org.hibernate.tool.hbm2ddl.SchemaExport execute
INFO: HHH000230: Schema export complete
Hibernate: select next_val as id_val from hibernate_sequence for update
Hibernate: update hibernate_sequence set next_val= ? where next_val=?
onSave
preFlush
Hibernate: insert into Person (name, id) values (?, ?)
postFlush
正如你可以看到,我們的印刷onSave
輸出,preFlush
和postFlush
,在大底AuditLogInterceptor.java
。
在postFlush
期間,您可以撥打publisher.sendObjectAddedMessage()
。在我看來,這將在所有情況下100%正常工作:)
要了解更多詳情,請參閱this示例。
如果您在發送該消息之前增加了時間,那麼可以嗎?該記錄出現在數據庫或缺少?或者在發送消息後註冊會出現在數據庫中? –
在第二臺機器上,我實現了「三次嘗試」機制(超時),這有時可以幫助,但並不經常。 – y434y