Hibernate postgresql通知功能

 董鹏飞80 发布于 2023-01-07 16:03

我正在编写一个使用hibernate + JPA作为ORM和postgresql 9.3作为数据库后端的应用程序,我需要对某些数据库事件做出反应.
更确切地说,我想在将新行插入表中时构建一个使用pg_notify()的触发器.
我已经读过这个,但所有的教程都是直接的jdbc连接,而不是通过hibernate.
我(认为我)不能使用hibernate事件,因为行不是通过hibernate插入的,而是通过第三方应用程序插入的.

有什么方法可以通过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上创建,并通过jndi由app访问.此外,EntityManager由容器注入Spring.这是我的代码:

@Named
public class PostgresqlLowLevelNotificationDAOImpl implements PostgresqlLowLevelNotificationDAO{

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

@Override
public ArrayList getNotifications(){

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

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

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

    });

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

}

- 更新
我修复了classcast异常:

@Override
public ArrayList getNotifications(){

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


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

        @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提出的解决方案后,当我取消部署app时,我在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(); 
    }

}

Neil McGuiga.. 5

    为什么在这里需要休眠?只需使用JDBC。无论如何,您可能都希望触发应用程序范围的事件(例如,发送Websocket消息或释放ehcache),如果您需要进行休眠操作,请订阅该事件并使用Hibernate进行操作。

    http://impossibl.github.io/pgjdbc-ng/是您的朋友。无需轮询。

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

1 个回答
    1. 为什么在这里需要休眠?只需使用JDBC。无论如何,您可能都希望触发应用程序范围的事件(例如,发送Websocket消息或释放ehcache),如果您需要进行休眠操作,请订阅该事件并使用Hibernate进行操作。

      http://impossibl.github.io/pgjdbc-ng/是您的朋友。无需轮询。

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

    2023-01-07 16:05 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有