Sources for the fixes:
- Hibernate : No CurrentSessionContext configured
- Hibernate 5 :- org.hibernate.MappingException: Unknown entity
- Replacement for org.hibernate.Transactions.isActive() in Hibernate 5
- Hibernate - ServiceRegistryBuilder
Concept
In Vaadin 7 the Application class was replaces with the UI class. Instead of configuring the web.xml, VaadinServlet can be used with the proper annotations.
Instead of transaction listeners, servlet filters can be used to intercept the request and manage the session.
The following is gpiercey's implementation that is updated for Hibernate 5.0.1
Interceptor
@WebFilter(urlPatterns = { "/*" }, dispatcherTypes = { DispatcherType.REQUEST, DispatcherType.FORWARD,
DispatcherType.INCLUDE, DispatcherType.ERROR })
public class SessionInterceptor implements Filter
{
private static final ApplicationLogger logger = new ApplicationLogger(SessionInterceptor.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
logger.executionTrace();
}
@Override
public void destroy()
{
logger.executionTrace();
final Session session = DatabaseUtil.getSessionFactory().getCurrentSession();
if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
session.getTransaction().commit();
if (session.isOpen())
session.close();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
final Session session = DatabaseUtil.getSessionFactory().getCurrentSession();
try
{
if (session.getTransaction().getStatus() != TransactionStatus.ACTIVE)
session.beginTransaction();
chain.doFilter(request, response);
if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
session.getTransaction().commit();
}
catch (StaleObjectStateException e)
{
logger.error(e);
if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
session.getTransaction().rollback();
throw e;
}
catch (Throwable e)
{
logger.error(e);
if (session.getTransaction().getStatus() == TransactionStatus.ACTIVE)
session.getTransaction().rollback();
throw new ServletException(e);
}
}
}
Database Util
public class DatabaseUtil
{
private final static ApplicationLogger logger = new ApplicationLogger(DatabaseUtil.class);
private final static SessionFactory sessionFactory;
private final static String CONFIG = "/path/to/hibernate.cfg.xml";
static
{
try
{
logger.trace("Initializing DatabaseUtil");
/**
*
*/
sessionFactory = new Configuration().configure(CONFIG).buildSessionFactory();
}
catch (Throwable e)
{
logger.error(e);
throw new ExceptionInInitializerError(e);
}
}
public static SessionFactory getSessionFactory()
{
logger.executionTrace();
if (sessionFactory.getCurrentSession().getTransaction().getStatus() != TransactionStatus.ACTIVE)
sessionFactory.getCurrentSession().beginTransaction();
return sessionFactory;
}
}
Hibernate Configuration
Current session context property has to be added to the Hibernate Configuration:
<property name="hibernate.current_session_context_class">org.hibernate.context.internal.ThreadLocalSessionContext</property>
Maven Dependencies
The following repository and dependencies were used:
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
<dependency>
<groupId>org.vaadin.addons</groupId>
<artifactId>hbncontainer</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
Usage
Now for database calls from the WebApp you can use the followings:final Session session = DatabaseUtil.getSessionFactory().getCurrentSession();
final Transaction transaction = session.getTransaction();
Exaple: UI and VaadinServlet class
@SuppressWarnings("serial")
@Theme("mytheme")
public class MyUI extends UI {
@WebServlet(value = "/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = MyUI.class)
public class MyServlet extends VaadinServlet {}
@Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
TextField message = new TextField();
message.setCaption("Type your message here:");
Button writeButton = new Button("Write to database");
writeButton.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
getNewSession().save(new Message(message.getValue()));
layout.addComponent(new Label("Written to database."));
}
});
Button readButton = new Button("Read from database");
readButton.addClickListener(new Button.ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
List<Message> result = getNewSession().createQuery("from Message").list();
for (Message msg : result) {
layout.addComponent(new Label(msg.getId() + " " + msg.getText()));
}
layout.addComponent(new Label("Read from database."));
}
});
layout.addComponents(message, writeButton, readButton);
}
private Session getNewSession() {
return DatabaseUtil.getSessionFactory().getCurrentSession();
}
}
No comments:
Post a Comment