[英]Hibernate postgresql notify functionality
我正在编写一个使用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<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();
}
}
为什么你需要Hibernate? 只需使用JDBC。 你可能想要发起一个应用程序范围的事件(也许是发送一个websocket msg或者破坏ehcache),如果你需要做一些事情,请订阅那个事件并用Hibernate做一些事情。
http://impossibl.github.io/pgjdbc-ng/是你的朋友。 不需要投票。
请参阅http://blog.databasepatterns.com/2014/04/postgresql-nofify-websocket-spring-mvc.html
Hibernate没有对PostgreSL通知的直接支持,因为这是一个特定的数据库功能,并非所有数据库供应商都支持它,并且它不适合ORM框架职责。
不过,您仍然可以尝试将其挂钩到当前正在运行的事务中。 您需要访问当前数据库连接, 添加监听挂钩 。
这可以通过Session.doWork()支持来完成:
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
//add some statement if it's required
PGNotification notifications[] = ((PGConnection) connection).getNotifications();
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.