Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何确保记录已添加到数据库中?_Java_Hibernate_Postgresql_Tapestry - Fatal编程技术网

Java 如何确保记录已添加到数据库中?

Java 如何确保记录已添加到数据库中?,java,hibernate,postgresql,tapestry,Java,Hibernate,Postgresql,Tapestry,我有两份申请: 第一个将记录插入postgresql数据库(假设它的id等于X),并通知第二个 被通知者向用户发送邮件,但在此之前,它会检查id为X的记录(它包含在第一台机器的“通知消息”中)是否插入到数据库中 在99%的情况下,它运行良好,但有时第二台机器无法找到具有给定id的记录。这是怎么可能的 在第一台机器上,我使用hibernate并将对象保存到数据库中,如下所示: objectDao.save(object); 然后发送消息: publisher.sendObjectAddedM

我有两份申请:

  • 第一个将记录插入postgresql数据库(假设它的id等于X),并通知第二个
  • 被通知者向用户发送邮件,但在此之前,它会检查id为X的记录(它包含在第一台机器的“通知消息”中)是否插入到数据库中
在99%的情况下,它运行良好,但有时第二台机器无法找到具有给定id的记录。这是怎么可能的

在第一台机器上,我使用hibernate并将对象保存到数据库中,如下所示:

objectDao.save(object);
然后发送消息:

publisher.sendObjectAddedMessage(user.getId(), ipSource.getIpAddress(), object.getId());
没什么特别的。我试图立即刷新hibernate,或者在发送消息之前稍等片刻,但随后出现了问题

我的PostgreSQL版本是:

PostgreSQL 9.3.5 on x86_64-unknown-linux-gnu, compiled by gcc (Debian 4.7.2-5) 4.7.2, 64-bit

也许您应该尝试使用事件侦听器(@PostPersist)? 例如


强烈建议您使用一些事件侦听器调用publisher.sendObjectAddedMessage()

i、 例如,您应该创建一个侦听器,该侦听器将在任何对象被持久化后调用一个方法,以确保在实体被持久化之前不会调用您的
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
    ...
}

现在考虑我的代码>主< /代码>类。您可以看到,我已经创建了

AuditLogInterceptor
,并将其与会话相关联

通过将此拦截器与会话关联,它将调用此拦截器的几种方法,如
onSave
preFlush
postfush
方法。这将确保在需要时始终调用这些方法。(如
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
的代码。它实现了hibernate的
EmptyInterceptor
接口。正如您在
Test.java
中所知道的,我们将会话与这个拦截器相关联。因此,它的重写方法将在几个事件(如保存、更新等)上调用

AuditLoginInterceptor.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   
如您所见,我们在
AuditLogInterceptor.java
中的colsole上打印了
save
preFlush
postlush

postFlush
期间,您可以调用您的
publisher.sendObjectAddedMessage()
。在我看来,这将在所有情况下100%正常工作:)


要了解更多详细信息,请参阅示例。

如果您在发送该消息之前增加时间,可以吗?记录出现在db上还是丢失?在第二台机器上,我实现了“三次尝试”机制(超时),这有时会有所帮助,但并不经常。
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