Piszę aplikację, która używa hibernacji + JPA jako ORM i postgresql 9.3 jako zaplecza bazy danych i muszę zareagować z pewnym kodem java do niektórych zdarzeń bazy danych.
Aby być bardziej precyzyjnym chcę zbudować wyzwalacz, który używa pg_notify(), gdy nowy wiersz jest wstawiony do tabeli.
Przeczytałem o tym, ale wszystkie tutoriale były z bezpośrednim połączeniem jdbc, a nie przez hibernację.
Ja (myślę, że ja) nie można używać zdarzeń hibernacji, ponieważ wiersze nie są wstawiane przez hibernację, ale przez aplikację innej firmy.Hibernate postgresql powiadamia funkcjonalność
Czy istnieje sposób, aby otrzymywać powiadomienia wysyłane z pg_notify przez hibernację?
- aktualizacja
Teraz mam 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)
muszę wspomnieć, że używam GlassFish 4.0 jako AS. Pula połączeń jest tworzona na glassfish i jest dostępna przez aplikację za pośrednictwem jndi. Również EntityManager jest wstrzykiwany przez pojemnik ze sprężyną. Tu jest mój kodu:
@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);
}
}
- aktualizacja
mam naprawione classcast wyjątek:
@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;
}
});
Ale to wciąż wydaje się, że nie otrzymują powiadomień.
Aktualizacja ---
Po I wprowadziły rozwiązania zaproponowanego przez Neila mam ten błąd w GlassFish dzienników kiedy undeploy aplikacji:
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 [[email protected]]) and a value of type [io.netty.buffer.PoolThreadCache] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.internal.ThreadLocalRandom] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.buffer.PoolThreadCache] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.util.Recycler.Stack] (value [[email protected]]) 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 [[email protected]]) and a value of type [io.netty.buffer.PoolThreadCache] (value [[email protected]]) 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.
muszę wspomnieć, że zniszczyć() metoda jest wywoływana, gdy aplikacja została wycofana. A jeśli szpieguję z visualVM wątek wciąż żyje po tym, jak aplikacja została usunięta.
public void destroy(){
try{
Statement statement = pgConnection.createStatement();
statement.addBatch("UNLISTEN xxxTest");
statement.executeBatch();
statement.close();
}catch(SQLException sqle) {
sqle.printStackTrace();
}
}
Potrzebuję hibernacji, ponieważ chciałem być typową konfiguracją aplikacji i korzystać z tych samych zasobów. Dzięki za wskazówki, przyjrzę się. –
Mam zaimplementowane z pgjdbc-ng i bez hibernacji i wydaje się, że działa :) dzięki Neil. –
Wygląda na to, że są 2 problemy: 1. Istnieje jeden wątek, który pozostaje aktywny, nawet jeśli aplikacja nie zostanie wdrożona. 2. Działa tylko wtedy, gdy dwa razy wdrożę aplikację. Myślę, że ma to coś wspólnego z pozostałym otwartym wątkiem ... –