Olá pessoal,
Alguem sabe como fazer o filter para o caso do open sesion in view com JPA? Já que o mesmo nao possui o recurso session.
Esse exemplo é do site do Jboss! Alguem sabe como alterar para funcionar com JPA?
Vlw
public class HibernateSessionRequestFilter implements Filter {
private static Log log = LogFactory.getLog(HibernateSessionRequestFilter.class);
private SessionFactory sf;
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
try {
log.debug("Starting a database transaction");
sf.getCurrentSession().beginTransaction();
// Call the next filter (continue request processing)
chain.doFilter(request, response);
// Commit and cleanup
log.debug("Committing the database transaction");
sf.getCurrentSession().getTransaction().commit();
} catch (StaleObjectStateException staleEx) {
log.error("This interceptor does not implement optimistic concurrency control!");
log.error("Your application will not work until you add compensation actions!");
throw staleEx;
} catch (Throwable ex) {
// Rollback only
ex.printStackTrace();
try {
if (sf.getCurrentSession().getTransaction().isActive()) {
log.debug("Trying to rollback database transaction after exception");
sf.getCurrentSession().getTransaction().rollback();
}
} catch (Throwable rbEx) {
log.error("Could not rollback transaction after exception!", rbEx);
}
// Let others handle it... maybe another interceptor for exceptions?
throw new ServletException(ex);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
log.debug("Initializing filter...");
log.debug("Obtaining SessionFactory from static HibernateUtil singleton");
sf = HibernateUtil.getSessionFactory();
}
public void destroy() {}
}
cara é muito simples
public class HibernateSessionRequestFilter implements Filter {
public void init(FilterConfig config) throws ServletException{}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HibernateUtil.beginTransaction();
try {
//response.setContentType("text/html; charset=UTF-8");//opcional
chain.doFilter(request, response);
HibernateUtil.commitTransaction();
} catch (HibernateException exception) {
exception.printStackTrace();
HibernateUtil.rollbackTransaction();
} finally {
HibernateUtil.closeSession();
}
}
/**
* Finalização da classe exige também sua reescrita
*/
public void destroy(){}
}
onde o hibernate util pode ser
public class HibernateUtil {
private static final SessionFactory SESSION_FACTORY;
private static final ThreadLocal SESSION_THREAD = new ThreadLocal();
private static final ThreadLocal TRANSACTION_THREAD = new ThreadLocal();
static {
try {
AnnotationConfiguration configuration = new AnnotationConfiguration();
configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
configuration.setProperty("hibernate.connection.datasource", "seupool");//configurado no glassfish
configuration.setProperty("hibernate.order_updates", "true");
configuration.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
configuration.setProperty("hibernate.show_sql", "false");
configuration.setProperty("hibernate.format_sql", "true");
configuration.setProperty("hibernate.current_session_context_class", "thread");
Scanner.scan(Thread.currentThread().getContextClassLoader(), Collections.EMPTY_SET, Collections.EMPTY_SET, configuration);//é um metodo que efetua o addanotationclass automatico ou você pode fazer varios addannotationsclass e substituir esse metodo.
SESSION_FACTORY = configuration.buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() {
if (SESSION_THREAD.get() == null) {
Session session = SESSION_FACTORY.openSession();
SESSION_THREAD.set(session);
}
return (Session) SESSION_THREAD.get();
}
public static void closeSession() {
Session session = (Session) SESSION_THREAD.get();
if (session != null && session.isOpen()) {
SESSION_THREAD.set(null);
session.close();
}
}
public static void beginTransaction() {
Transaction transaction = getSession().beginTransaction();
TRANSACTION_THREAD.set(transaction);
}
public static void commitTransaction() {
Transaction transaction = (Transaction) TRANSACTION_THREAD.get();
if (transaction != null && !transaction.wasCommitted() && !transaction.wasRolledBack()) {
transaction.commit();
TRANSACTION_THREAD.set(null);
}
}
public static void rollbackTransaction() {
Transaction transaction = (Transaction) TRANSACTION_THREAD.get();
if (transaction != null && !transaction.wasCommitted() && !transaction.wasRolledBack()) {
transaction.rollback();
TRANSACTION_THREAD.set(null);
}
}
}
no seu web.xml coloque
<filter>
<filter-name>HibernateFilter</filter-name>
<filter-class>br.com.empresa.pacote.HibernateSessionRequestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Vlw,
No meu MB eu devo chamar o HibernateUtil.beginTransaction e HibernateUtil.closeSession? Ou o HibernateSessionRequestFilter faz isso automaticante?
não precisa mais de fechar!
na hora de usar se for para listar dê um getSession().clear(); e um return getSession().creatquery… apenas
e se for para salvar em varias tabelas e exigir um comit só no final use no inicio o getSession().begintransaction etc…
e nada de fechar mais nas listas!
Então a principal sacada para resolver esse problema é deixar o EntityManager (Session) como estatico?
E depois fazer o filtro para dar o commit/roolback tirando essa responsabilidade das classes?
É isso mesmo?
Vlw
[quote=apalmeira]Então a principal sacada para resolver esse problema é deixar o EntityManager (Session) como estatico?
E depois fazer o filtro para dar o commit/roolback tirando essa responsabilidade das classes?
É isso mesmo?
Vlw
[/quote]
sim, seus DAOs podem extender ao HibernateUtil dando funcionalidade direto ao getSession sendo ele static