java - Hibernate postgresql 通知功能

标签 java database hibernate postgresql jpa

我正在编写一个使用 hibernate + JPA 作为 ORM 和 postgresql 9.3 作为数据库后端的应用程序,我需要使用一些 java 代码对一些数据库事件使用react。
更准确地说,我想构建一个触发器,在向表中插入新行时使用 pg_notify()。
我已经阅读过相关内容,但所有教程都是直接连接 jdbc 而不是通过 hibernate。
我(认为我)不能使用 hibernate 事件,因为行不是通过 hibernate 插入的,而是通过第 3 方应用程序插入的。

有什么方法可以通过 hibernate 接收使用 pg_notify 发送的通知吗?

-- 更新
现在我有一个 classCastException :

java.lang.ClassCastException: com.sun.gjc.spi.jdbc40.ConnectionWrapper40 cannot be cast to org.postgresql.PGConnection
    at com.xxx.core.impl.dao.PostgresqlLowLevelNotificationDAOImpl$1.execute(PostgresqlLowLevelNotificationDAOImpl.java:36)
    at com.xxx.core.impl.dao.PostgresqlLowLevelNotificationDAOImpl$1.execute(PostgresqlLowLevelNotificationDAOImpl.java:1)

我必须提到我使用 Glassfish 4.0 作为 AS。连接池在glassfish上创建,app通过jndi访问。 EntityManager 也由带有 Spring 的容器注入(inject)。这是我的代码:

@Named
public class PostgresqlLowLevelNotificationDAOImpl implements PostgresqlLowLevelNotificationDAO{

    @PersistenceContext(type =PersistenceContextType.TRANSACTION,synchronization=SynchronizationType.SYNCHRONIZED,unitName="CCPU")
    private EntityManager em;

@Override
public ArrayList<PGNotification> getNotifications(){

    Session session = em.unwrap(Session.class);

    PGNotification[] notifications = session.doReturningWork(new ReturningWork<PGNotification[]>() {

        @Override
        public PGNotification[] execute(Connection connection) throws SQLException {
            PGNotification[] notifications = ((PGConnection) connection).getNotifications();
            return notifications;
        }

    });

    return (ArrayList) Arrays.asList(notifications);
}   

-- 更新
我已经修复了类广播异常:

@Override
public ArrayList<PGNotification> getNotifications(){

    Session session = em.unwrap(Session.class);


    PGNotification[] notifications = session.doReturningWork(new ReturningWork<PGNotification[]>() {

        @Override
        public PGNotification[] execute(Connection connection) throws SQLException {

            PGConnection pgc = null; 

            if (connection.isWrapperFor(PGConnection.class)) {
                pgc = (PGConnection) connection.unwrap(PGConnection.class);
            }                               

            PGNotification[] notifications = pgc.getNotifications();                
            return notifications;
        }
    });

但我似乎仍然没有收到通知。

更新---
在我实现了 Neil 提出的解决方案之后,当我取消部署应用程序时,我在 glassfish 日志中遇到了这个错误:

    2014-06-27T11:03:24.278+0300|SEVERE: The web application [/myApp] created a ThreadLocal    with key of type [io.netty.buffer.PooledByteBufAllocator$1] (value [io.netty.buffer.PooledByteBufAllocator$1@28ad6479]) and a value of type [io.netty.buffer.PoolThreadCache] (value [io.netty.buffer.PoolThreadCache@f9f58cc]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.279+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@267ec117]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@4bb6e0bf]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.279+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@535d426e]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@fb46e84]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.280+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.internal.ThreadLocalRandom$2] (value [io.netty.util.internal.ThreadLocalRandom$2@ec3a42a]) and a value of type [io.netty.util.internal.ThreadLocalRandom] (value [io.netty.util.internal.ThreadLocalRandom@4e4ec8f8]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.280+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@166c39f2]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@1b504a5e]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.281+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@34426f54]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@759b0e99]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.282+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.concurrent.DefaultPromise$1] (value [io.netty.util.concurrent.DefaultPromise$1@16db9b21]) and a value of type [java.lang.Integer] (value [0]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.282+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@166c39f2]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@2ba59f40]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.282+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.buffer.PooledByteBufAllocator$1] (value [io.netty.buffer.PooledByteBufAllocator$1@28ad6479]) and a value of type [io.netty.buffer.PoolThreadCache] (value [io.netty.buffer.PoolThreadCache@67a3923]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.283+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@166c39f2]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@423d2c27]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.283+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.util.Recycler$1] (value [io.netty.util.Recycler$1@535d426e]) and a value of type [io.netty.util.Recycler.Stack] (value [io.netty.util.Recycler$Stack@3e1dd66a]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
2014-06-27T11:03:24.283+0300|SEVERE: The web application [/myApp] created a ThreadLocal with key of type [io.netty.buffer.PooledByteBufAllocator$1] (value [io.netty.buffer.PooledByteBufAllocator$1@28ad6479]) and a value of type [io.netty.buffer.PoolThreadCache] (value [io.netty.buffer.PoolThreadCache@18e7e902]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

我不得不提到当应用程序被取消部署时调用 destroy() 方法。 而且,如果我使用 visualVM 进行监视,则在取消部署应用程序后线程仍然存在。

public void destroy(){

    try{
        Statement statement = pgConnection.createStatement();                  
        statement.addBatch("UNLISTEN xxxTest");
        statement.executeBatch();
        statement.close();          
    }catch(SQLException sqle)   {
        sqle.printStackTrace(); 
    }

}

最佳答案

  1. 这里为什么需要 Hibernate?只需使用 JDBC。您可能无论如何都想触发一个应用程序范围的事件(可能发送一个 websocket 消息或破坏一个 ehcache),如果您需要在 hibernate 状态下做一些事情,请订阅该事件并用 hibernate 状态做一些事情。

    <
  2. http://impossibl.github.io/pgjdbc-ng/是你的 friend 。无需轮询。

参见 http://blog.databasepatterns.com/2014/04/postgresql-nofify-websocket-spring-mvc.html

关于java - Hibernate postgresql 通知功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24423142/

相关文章:

java - 在静态测试文件中调用非静态方法

java - 多个集合上的迭代器

java - 如何利用 Spring MVC 实现前端 Controller 但不使用 Controller

database - 在 Visual Studio 2015 中找不到数据生成计划

java - 如何在 Hibernate 中使用 pooled-lo 优化器

java - 在 Spring Boot 2.0.4.RELEASE 中的 RestController 中捕获 ArithmeticException

swift - IN 运算符的 Realm 查询速度慢

php - 如何查找和替换 MySQL 文本字段中的整个单词?

java - hibernate 跳过并采取一些行

java - 如何将类型化查询转换为条件生成器对象?