Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Native JavaScript functions within Vaadin
I've been developing an Application since 2015 March (moreover). From the beginning, what I wanted was using Hibernate and a DAO pattern for Data Access (I'm using PostgreSql database). This would be the architecture (don't laugh at me, I drawed using paint :p):
Everything has been working, somehow, correctly. Now, we need to introduce Google Charts to our application. Google charts. To use common and plain javascript code, my solution has been creating a Custom Component with a Label, containing HTML code (div). Then executing a javascript function, which loads a google chart and renders it in the div. So, I developed a Restful WS to interact with the database. The architecture is what follows:However, I'm facing some problems.
- When I execute the methods of the WS, the results are always identical (you'll know afterwards why I say identical).
- When the page is loaded (the View), the results returned by the WS aren't correct. This is a DAO method to fetch some values:
public HashMap<LocalDate, Integer> getCantidadDeRutasPorPlanes(LocalDate pInicio, LocalDate pFin){
System.out.println("getCantidadDeRutasPorPlanes() entre "
+ DateTimeFormatters.JavaDateTimeFormatter.formatDate(pInicio)
+ " y "
+ DateTimeFormatters.JavaDateTimeFormatter.formatDate(pFin));
HashMap<LocalDate, Integer> ret = new HashMap<LocalDate, Integer>();
for(LocalDate aux = pInicio;
aux.isBefore(pFin) || aux.isEqual(pFin);
aux = aux.plusDays(1)){
Integer value = getCantidadDeRutasPorPlan(aux);
ret.put(aux, value);
}
return ret;
}
private Integer getCantidadDeRutasPorPlan(LocalDate pFecha) {
try{
Query q = session
.createQuery("select size(p.lasRutas) from Plan p where day(p.laFecha)=:dia and month(p.laFecha)=:mes and year(p.laFecha)=:anyo");
q.setInteger("dia", pFecha.getDayOfMonth());
q.setInteger("mes", pFecha.getMonthValue());
q.setInteger("anyo", pFecha.getYear());
Integer cantidad = 0;
List lista = q.list();
if(lista != null){
if(!lista.isEmpty()){
for (Object obj : lista) {
if(obj != null){
Integer cant = (Integer) obj;
cantidad += cant;
}
}
}
}
System.out.println("getCantidadDeRutasPorPlan(): " + cantidad);
return cantidad;
}catch(HibernateException e){
logger.error("Error HibernateException en getCantidadDeRutasPorPlan(): " + e.getMessage());
System.err.println("Error HibernateException en getCantidadDeRutasPorPlan(): " + e.getMessage());
e.printStackTrace();
return -1;
}
}
As you can see, when an exception is caught the returned value is -1. So, when loading the page and drawing charts, several exceptions happen and pseudo-random data is loaded. E.g: 0,0,-1,-1,-1,0,0,-1,0,-1...
However, when calling manually (with SOAP UI) the WS method which executes the same DB method, the results are correct, e.g. 0,0,0,2,0,0,1,0,0,...
With regard to the web service i guess there is no problem. So, there are two possible reasons why this doesn't work correctly:
- I'm using a trick to make google charts work on Vaadin. Perhaps I should integrate it with server-client side methodology of Vaadin as said here. I know JavaScript is executed on the client side. Vaadin, on the other hand, is server side. The Web Service is executed on the server, using the same dao.
- Otherwise, as you can see in bold, the problem may be the following: vaadin application and the web service both share the same DAO class. I didn't want to introduce code (at least the relevant code) regarding the DAO, but now I consider helpful so that anybody can comment out her/his impression.
- PtDao is the DAO class itself and follows Singleton pattern, where all the stuff related to Hibernate, HQL and session is located.
- PtService is an interface. It contains every method of PtDao which is wanted to be usable.
- PtDaoService implements PtService and it contains the instance of PtDao as attribute. So, in every method (which is named equally as in PtDao) it's called dao.theMethod(params);
Let's see in action:
PtDao
public class PtDao {
/*
* Atributos
*/
private Logger logger = LoggerFactory.getLogger(PtDao.class);
private ConfiguracionNueva config;
private static PtDao myPtDao = null;
private Configuration cfg;
private SessionFactory factory;
private Transaction tx;
private static Session session;
private static ServiceRegistry serviceRegistry;
// Flota is a singleton which contains cars and drivers (two lists)
private Flota flota = Flota.getInstance();
/*
* Métodos
*/
private PtDao() {
try {
config = new ConfiguracionNueva();
config.leerConfiguracion();
//cfg = new Configuration().configure("hibernate.cfg.xml"); // configures settings from hibernate.cfg.xml
cfg = new Configuration();
//cfg.configure();
cfg.setProperty("hibernate.hbm2ddl.auto", "update");
cfg.setProperty("hibernate.transaction.auto_close_session", "false");
cfg.setProperty("hibernate.connection.autocommit", "false");
// Configuración PostgreSQL
cfg.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
cfg.setProperty("hibernate.connection.url", "jdbc:postgresql://"
+ config.getIP_POSTGRESQL() + ":"
+ config.getPORT_POSTGRESQL() + "/"
+ config.getDATABASE_POSTGRESQL());
cfg.setProperty("hibernate.connection.username", config.getUSERNAME_POSTGRESQL());
cfg.setProperty("hibernate.connection.password", config.getPASSWORD_POSTGRESQL());
cfg.setProperty("dialect", "org.hibernate.dialect.PostgreSQLDialect");
// C3p0 connection pool
cfg.setProperty("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");
cfg.setProperty("c3p0.min_size", "3");
cfg.setProperty("c3p0.max_size", "10");
cfg.setProperty("c3p0.timeout", "1000");
cfg.setProperty("c3p0.idle_test_period", "2000");
cfg.setProperty("c3p0.preferredTestQuery", "select 1;");
cfg.setProperty("hibernate.connection.release_mode", "after_transaction");
cfg.setProperty("hibernate.show_sql", "false");
cfg.setProperty("hibernate.format_sql", "true");
cfg.setProperty("hibernate.generate_statistics", "true");
// Meter clases y ficheros HBM
cfg.addResource("com/ingartek/cavwebapp/model/LatLng.hbm.xml");
// more hibernate mappings
StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
// If you miss the below line then it will complain about a missing
// dialect setting
serviceRegistryBuilder.applySettings(cfg.getProperties());
serviceRegistry = serviceRegistryBuilder.build();
factory = cfg.buildSessionFactory(serviceRegistry);
this.openSession();
} catch (ConfigurationException e) {
System.err.println("Error ConfigurationException en PtDao(): " + e.getMessage() + ". Causa: " + e.getCause());
logger.error("Error ConfigurationException en PtDao(): " + e.getMessage() + ". Causa: " + e.getCause());
e.printStackTrace();
} catch (HibernateException e) {
System.err.println("Error HibernateException en PtDao(): " + e.getMessage() + ". Causa: " + e.getCause());
logger.error("Error HibernateException en PtDao(): " + e.getMessage() + ". Causa: " + e.getCause());
e.printStackTrace();
}
}
private void openSession() throws HibernateException {
session = factory.openSession();
}
private void closeSession() {
session.close();
}
private void beginTransaction() {
this.tx = null;
this.tx = session.beginTransaction();
}
private void commitTransaction() throws HibernateException {
this.tx.commit();
}
private void rollbackTransaction() throws HibernateException {
if (this.tx != null)
this.tx.rollback();
}
public static PtDao getPtDao() {
if (myPtDao == null) {
myPtDao = new PtDao();
}
return myPtDao;
}
// Login: simple login
public Administrador loginAdministrador(String pUsername, String pPassword)
throws IncorrectPasswordOrUserNotFoundException {
System.out.println("Intentando identificar a " + pUsername);
Query q = session
.createQuery("from Administrador as ad where ad.user=:username and ad.pass=:password");
q.setString("username", pUsername);
q.setString("password", pPassword);
@SuppressWarnings("unchecked")
Iterator<List<Administrador>> it = q.list().iterator();
if (!it.hasNext()) {
throw new IncorrectPasswordOrUserNotFoundException(pUsername);
} else {
Administrador admin = (Administrador) it.next();
return admin;
}
}
...
// Simple write method
public Vehiculo anadirVehiculo(String pMatricula, String pNombre,
Integer pAsientos) throws ExisteVehiculoException {
System.out.println("Creando nuevo vehículo");
if (!isMatriculaUsada(pMatricula)) {
Vehiculo unVehiculo = new Vehiculo(pMatricula, pNombre, pAsientos);
if (!flota.existeVehiculo(unVehiculo)) {
flota.anadirVehiculo(unVehiculo);
}
try {
beginTransaction();
session.save(unVehiculo);
commitTransaction();
return unVehiculo;
} catch (HibernateException e) {
System.err
.println("Error HibernateException en anadirVehiculo(): "
+ e.getMessage() + ". Causa: " + e.getCause());
e.printStackTrace();
return null;
}
} else {
rollbackTransaction();
throw new ExisteVehiculoException();
}
}
...
// One of the methods to draw Google Charts
public HashMap<LocalDate, Integer> getCantidadDeRutasPorPlanes(LocalDate pInicio, LocalDate pFin){
System.out.println("getCantidadDeRutasPorPlanes() entre "
+ DateTimeFormatters.JavaDateTimeFormatter.formatDate(pInicio)
+ " y "
+ DateTimeFormatters.JavaDateTimeFormatter.formatDate(pFin));
HashMap<LocalDate, Integer> ret = new HashMap<LocalDate, Integer>();
for(LocalDate aux = pInicio;
aux.isBefore(pFin) || aux.isEqual(pFin);
aux = aux.plusDays(1)){
Integer value = getCantidadDeRutasPorPlan(aux);
ret.put(aux, value);
}
return ret;
}
private Integer getCantidadDeRutasPorPlan(LocalDate pFecha) {
try{
Query q = session
.createQuery("select size(p.lasRutas) from Plan p where day(p.laFecha)=:dia and month(p.laFecha)=:mes and year(p.laFecha)=:anyo");
q.setInteger("dia", pFecha.getDayOfMonth());
q.setInteger("mes", pFecha.getMonthValue());
q.setInteger("anyo", pFecha.getYear());
Integer cantidad = 0;
List lista = q.list();
if(lista != null){
if(!lista.isEmpty()){
for (Object obj : lista) {
if(obj != null){
Integer cant = (Integer) obj;
cantidad += cant;
}
}
}
}
System.out.println("getCantidadDeRutasPorPlan(): " + cantidad);
return cantidad;
}catch(HibernateException e){
logger.error("Error HibernateException en getCantidadDeRutasPorPlan(): " + e.getMessage());
System.err.println("Error HibernateException en getCantidadDeRutasPorPlan(): " + e.getMessage());
e.printStackTrace();
return -1;
}
}
PtService
public interface PtService {
public Administrador loginAdministrador(String pUsername, String pPassword) throws IncorrectPasswordOrUserNotFoundException;
public Vehiculo anadirVehiculo(String pMatricula, String pNombre, Integer pAsientos) throws ExisteVehiculoException;
public HashMap<LocalDate, Integer> getCantidadDeRutasPorPlanes(LocalDate pInicio, LocalDate pFin);
}
PtDaoService
public class PtDaoService implements PtService {
/*
* Atributos
*/
private PtDao dao;
/*
* Métodos
*/
public PtDaoService(){
this.dao = PtDao.getPtDao();
}
@Override
public Administrador loginAdministrador(String pUsername, String pPassword)
throws IncorrectPasswordOrUserNotFoundException {
return dao.loginAdministrador(pUsername, pPassword);
}
@Override
public Vehiculo anadirVehiculo(String pMatricula, String pNombre,
Integer pAsientos) throws ExisteVehiculoException{
return dao.anadirVehiculo(pMatricula, pNombre, pAsientos);
}
@Override
public HashMap<LocalDate, Integer> getCantidadDeRutasPorPlanes(LocalDate pInicio, LocalDate pFin) {
return dao.getCantidadDeRutasPorPlanes(pInicio, pFin);
}
}
Do you see any trouble in here?
What do you think of my approach?
Thanks in advance...