SAP HANA Cloud Platform + Vaadin – a combo for productive web app development
SAP HANA is a rather interesting, efficient in-memory database. It can be purchased as a “black box” server (rented hardware, with pre-installed software) that you place to your server room or simply use as a cloud service. Together with the actual RDBMS, you can use SAP HANA Cloud Platform execution environments to host your business apps.
Vaadin is a powerful UI framework that you can easily use together with SAP HANA Cloud Platform (HCP). With it, you’ll most often be working with plain Java and can completely forget that you are building a complex modern web application. The programming model is quite similar to Java Swing, the UI logic lives securely on the server’s JVM and in the browser, there is only a small auto-generated thin client that communicates securely and efficiently with the server. And it’s opensource and free to use, under the Apache 2 license.
There are lots of different kinds of applications, that all have their custom requirements, but for most business apps, Vaadin is an excellent alternative to a client side development model, such as SAPUI5. The performance boost that you, as a developer, will gain from the pure Java/JVM approach of Vaadin is unparalleled.
Let’s have a look at how you can set up a SAP HANA Cloud Platform application, with a Vaadin based UI, that you execute in the HCP. I’m also covering a bit of some best practices for project setup and JPA usage, which might be interesting, even if you’re using or planning to use something else besides Vaadin.
Setting up a SAP HANA Cloud Platform development environment
Once you have downloaded the development package, you could check out the bundled examples. I derived this example from the official persistence-with-ejb example which provides a solid basis for your application. In the project setup, there is something that I’d do a bit differently though. Emphasizing Maven conventions and a bit stronger modularization will probably save a lot of time in the future.
The first thing I suggest to do when starting with HCP development is to create a Maven profile to store some common properties in. In the default examples, this is dealt with a parent project, but this is probably more handy if you have lots of small HCP projects. An example of such a profile definition is found in the project’s readme-file. You should replace the path to the SDK with the one in your environment and replace the defaults with your own username-password combination.
Our final project will be split into a backend and a UI module, both built by the master project. To the backend module, I’m placing all JPA stuff and the EJB via entities that should be fetched and updated. This part of the application is pretty much the same (~ 100% re-usable), whether you’re building your application with Vaadin, any other UI technology or if you’re just publishing REST services for third party developers.
The UI module is a rather standard Java web application project, building a war file suitable for Java EE 6 execution environment. You could naturally combine all stuff (JPA model, EJB, Vaadin UI) to a project creating just one war file, but splitting your app into modules will help you to structure the re-usable parts better and helps to spread the effort to a larger team.
The folder structure for the final project looks like this (simplified):
project-root/ pom.xml hana-backend/ pom.xml src/... vaadin-ui/ pom.xml src/....
The backend module
The JPA model for the example is a bit like the official SAP EJB persistency example, but I wanted it to be a bit more advanced. I added another JPA entity, Team, to which there is a relation from the Person object. I also extracted an abstract super class for entities. To the AbstractEntity, I placed things like identifiers, hashCode, equals methods and timestamps, like created and lastModified. The superclass helps to avoid lots of boilerplate that’d need to be written to pretty much each and every entity.
This is what the AbstractEntity looks like:
@MappedSuperclass
public class AbstractEntity {
@Id
private String id;
@Temporal(TemporalType.TIMESTAMP)
private Date created;
@Temporal(TemporalType.TIMESTAMP)
private Date lastModified;
public AbstractEntity() {
this.id = UUID.randomUUID().toString();
}
// getters and setters are omitted
@PrePersist
public void onPrePersist() {
created = lastModified = new Date();
}
@PreUpdate
public void onPreUpdate() {
lastModified = new Date();
}
@Override
public int hashCode() {
return id.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof AbstractEntity)) {
return false;
}
return getId().equals(((AbstractEntity) obj).getId());
}
}
The actual entities (Person and Team) then become quite a bit simpler. The Team entity, with its one and only property, looks like this:
@Entity
@Table(name = "T_TEAMS")
public class Team extends AbstractEntity {
private String teamName;
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
@Override
public String toString() {
return teamName;
}
}
Although many J2EE veterans have a healthy allergy for EJBs, since Java EE 6 there are no excuses why you shouldn’t hide your JPA related code to an EJB. Stateless local EJB makes your code simpler, easier to write and maintain and it will also perform extremely well. If you write your DAO’s as EJB’s, you can, for example, forget transaction management most of the time as the container will intercept our service methods automatically.
Writing your JPA code to an EJB based service also gives you a nice separated module that you can re-use in many different applications, whether you were building rich web UI’s with Vaadin or low level REST services for third party application developers. The PersistenceFacade in my example, with one business method, is as simple as this:
@Stateless
@LocalBean
public class PersistenceFacade {
@PersistenceContext
private EntityManager em;
public List<Person> getAllPersons() {
return em.createQuery("select p from Person p", Person.class).getResultList();
}
I added the very simple JPQL example in the above, but most often I don’t suggest JPQL or Criteria API to access your JPA entities. I recently wrote an article series of three excellent JPA libraries, Spring Data, DeltaSpike Data and QueryDSL, that will help you to write queries in a more efficient manner. In this example, I used QueryDSL to write methods to e.g. filter Person entities with a string filter:
public List<Person> getPersonsMatching(String filter) {
JPAQuery query = new JPAQuery(em);
QPerson p = QPerson.person;
List<Person> list = query.from(p)
.where(
p.firstName.containsIgnoreCase(filter)
.or(p.lastName.containsIgnoreCase(filter)
)).list(p);
return list;
}
The QPerson class in the above code snippet is a helper class, automatically generated by QueryDSL, based on the JPA entities. This way QueryDSL allows you to write the queries with a well typed Java API. The advanced Java IDEs will then help you to write your queries so that they actually work on the first run, which is not that common with raw JPQL or SQL. 😉
The UI module
Vaadin UI modules are basically WAR files and are executed as a servlet behind the scenes. In the project’s pom.xml we add a dependency to our hana-backend module, so that the EJB containing the business logic is included in the produced WAR file.
Normally I’d strongly suggest to use Vaadin CDI to make UI classes CDI managed bean. CDI is kind of the glue that you can use to put together your well modularized Java EE services. As there are still some rough edges in the provided Java EE container, CDI support doesn’t fully work in all situations in the HCP.
The issue in the container is probably fixed pretty soon, but even without Vaadin CDI, it is still rather easy to use Vaadin in SAP HANA Cloud Platform. We can just use Servlet 3 style annotations to declare the servlet instance and injecting the EJB there works well. To actually use the EJB from Vaadin classes, I created a small static helper method (based on a “thread local” variable) to get access to the EJB from anywhere in the Vaadin code.
@WebServlet(urlPatterns = "/*", name = "HanaUIServlet")
@VaadinServletConfiguration(ui = HanaUI.class, productionMode = false)
public static class HanaUIServlet extends VaadinServlet {
@EJB
private PersistenceFacade personBean;
public PersistenceFacade getPersistenceFacade() {
return personBean;
}
}
public static PersistenceFacade getPersonBean() {
return ((HanaUIServlet) VaadinServlet.getCurrent()).getPersistenceFacade();
}
The hard part is now done. The rest is just simple component based UI development. If you have been building e.g. Swing based desktop applications before, you’ll really see the similarities with Vaadin immediately. The heart of this demo UI is the listing of Person entities to a table component in the UI (see HanaUI class) and the reusable PersonForm component that lets users edit the Person entities. The table is initialized like this:
MTable<Person> personList = new MTable<Person>(Person.class).withProperties(
"firstName", "lastName", "created", "lastModified");
In the init method, we populate the list like this:
personList.setBeans(getPersonBean().getAllPersons());
I’m using a Viritin helper library that provides some enhancements to the core Vaadin components. You can naturally do this with the core components or application specific helpers as well, but I like to emphasize the modularity that the Java ecosystem and Vaadin tackle so well. As you progress with Vaadin, you’ll probably want to do some domain specific libraries for yourself too. There are more than 500 different extensions and helpers available for Vaadin via Vaadin Directory today. If you think something might be missing from Vaadin, first check out the Directory.
There is also a typical UI to filter the person listing. The filtering is implemented with a TextField and a TextChangeListener, and the code shows how simple building UIs with Vaadin can be. Once the user types in and keeps a tiny pause, the client sends a tiny request to the server that initiates the following TextChangeListener, where we’ll create a filtered query to the backend and bind only the relevant rows to the table.
search.addTextChangeListener(new TextChangeListener() {
@Override
public void textChange(TextChangeEvent event) {
String text = event.getText();
if (StringUtils.isNotEmpty(text)) {
filterEntities(text);
} else {
// empty filter, list all
listEntities();
}
}
});
In the filterEntities method, we simply use the business method we built using QueryDSL in the previous chapter.
Getting forward with SAP HANA Cloud Platform and Vaadin
If you look at the full HanaUI class and composites like TeamSelect and the PersonForm class, you’ll get a pretty good picture of what Vaadin development is like. In a larger project, you’ll naturally have concerns like navigation and view management that you’ll want to tackle. To get examples and ideas of how to build your larger Vaadin application, check out the Book of Vaadin, join a local Vaadin meetup group or training and search for Vaadin examples in GitHub!
Thanks for sharing this nice primer on using Vaadin framework on HCP. Truly shows the power of openness: open PaaS + open source frameworks + open community (contributions)!
We made a video with our test application for SAP/HANA and vaadin UI (some time ago):
https://youtu.be/8EJvX2tKyyc?t=3m8s
(vaadin UI starts at 3:08)
Maybe as an enhancement add the vaadin repo to pom.xml took me a little to figure the errors
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
Submitted an issue in Github, i think PersonFacade should be PersistenceFacade
Yes, it looks like I did a refactoring in Eclipse before publishing the article that just didn't work properly and the project still compiled, but just for me. Sorry about the hassle, I have been using too much NetBeans lately so I didn't remember anymore how Eclipse "works". The github project should now work and the article should be fixed soon as well after it passes the moderation round.
Big thanks for pointing this out!
Thanks for the fix, but somehow i still can't get it to run properly, when i start a local server i get the following exception:
Happens when i deploy localy, any ideas?
Regards
Hi, Thats a pretty short error message 🙁 I never really tried with the local server. Does the basic EJB example that comes with the SDK work? Maybe there is an issue with the DBtunnel? Maybe I removed some dependency require for tunnel connection when I cleaned up the build.
cheers,
matti
When deploying into my account a get the same error + additional
Failed to load the widgetset: http://cdn.virit.in/ws/vwscdnc791d0c2f0b0cd53a58db36d1b880704/vwscdnc791d0c2f0b0cd53a58db36d1b880704.nocache.js
2015 06 16 07:29:43#+00#ERROR#org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/vaadin-ui].[HanaUIServlet]##anonymous#http-bio-8041-exec-2#na#ac98f8fe9#vaadin#web#ac98f8fe9#Servlet.service() for servlet [HanaUIServlet] in context with path [/vaadin-ui] threw exception [com.vaadin.server.ServiceException: javax.ejb.EJBException: The bean encountered a non-application exception; nested exception is:
javax.persistence.PersistenceException: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: org.apache.commons.dbcp.SQLNestedException: Borrow prepareStatement from pool failed
Error Code: 0
Call: SELECT ID, BIRTHDAY, CREATED, FIRSTNAME, LASTMODIFIED, LASTNAME, TEAM_ID FROM T_PERSONS
Query: ReadAllQuery(referenceClass=Person sql="SELECT ID, BIRTHDAY, CREATED, FIRSTNAME, LASTMODIFIED, LASTNAME, TEAM_ID FROM T_PERSONS")] with root causecom.sap.dbtech.jdbc.exceptions.jdbc40.SQLSyntaxErrorException: [-4004] (at 79): Unknown table name or unknown schema:T_PERSONS
at com.sap.dbtech.jdbc.exceptions.jdbc40.SQLSyntaxErrorException.createException(SQLSyntaxErrorException.java:53)
at com.sap.dbtech.jdbc.exceptions.SQLExceptionSapDB.createException(SQLExceptionSapDB.java:251)
at com.sap.dbtech.jdbc.exceptions.SQLExceptionSapDB.generateDatabaseException(SQLExceptionSapDB.java:138)
at com.sap.dbtech.jdbc.packet.ReplyPacket.createException(ReplyPacket.java:69)
at com.sap.dbtech.jdbc.ConnectionSapDB.throwSQLError(ConnectionSapDB.java:1099)
at com.sap.dbtech.jdbc.ConnectionSapDB.execute(ConnectionSapDB.java:723)
at com.sap.dbtech.jdbc.CallableStatementSapDB.sendCommand(CallableStatementSapDB.java:1840)
at com.sap.dbtech.jdbc.StatementSapDB.sendSQL(StatementSapDB.java:932)
at com.sap.dbtech.jdbc.CallableStatementSapDB.doParse(CallableStatementSapDB.java:234)
at com.sap.dbtech.jdbc.CallableStatementSapDB.constructor(CallableStatementSapDB.java:187)
at com.sap.dbtech.jdbc.CallableStatementSapDB.<init>(CallableStatementSapDB.java:99)
at com.sap.dbtech.jdbc.CallableStatementSapDBFinalize.<init>(CallableStatementSapDBFinalize.java:11)
at com.sap.dbtech.jdbc.ConnectionSapDB.prepareStatement(ConnectionSapDB.java:979)
at com.sap.dbtech.jdbc.trace.Connection.prepareStatement(Connection.java:413)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sap.core.persistence.jdbc.trace.TraceableBase$1.invoke(TraceableBase.java:44)
at com.sun.proxy.$Proxy36.prepareStatement(Unknown Source)
at com.sap.core.persistence.jdbc.trace.TraceableConnection.prepareStatement(TraceableConnection.java:121)
at org.apache.commons.dbcp.PoolingConnection.makeObject(PoolingConnection.java:285)
at org.apache.commons.pool.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:1220)
at org.apache.commons.dbcp.PoolingConnection.prepareStatement(PoolingConnection.java:107)
at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:281)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.prepareStatement(DatabaseAccessor.java:1551)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.prepareStatement(DatabaseAccessor.java:1500)
at org.eclipse.persistence.internal.databaseaccess.DatabaseCall.prepareStatement(DatabaseCall.java:778)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:619)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1995)
at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2714)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRows(ExpressionQueryMechanism.java:2667)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:477)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1155)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1114)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:402)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1202)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2894)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1797)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1779)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1744)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:468)
at org.vaadin.saphana.backend.PersistenceFacade.getAllPersons(PersistenceFacade.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.cdi.CdiInterceptor.invoke(CdiInterceptor.java:126)
at org.apache.openejb.cdi.CdiInterceptor.access$000(CdiInterceptor.java:42)
at org.apache.openejb.cdi.CdiInterceptor$1.call(CdiInterceptor.java:63)
at org.apache.openejb.cdi.CdiInterceptor.aroundInvoke(CdiInterceptor.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.monitoring.StatsInterceptor.record(StatsInterceptor.java:176)
at org.apache.openejb.monitoring.StatsInterceptor.invoke(StatsInterceptor.java:95)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext$Invocation.invoke(ReflectionInvocationContext.java:181)
at org.apache.openejb.core.interceptor.ReflectionInvocationContext.proceed(ReflectionInvocationContext.java:163)
at org.apache.openejb.core.interceptor.InterceptorStack.invoke(InterceptorStack.java:138)
at org.apache.openejb.core.stateless.StatelessContainer._invoke(StatelessContainer.java:239)
at org.apache.openejb.core.stateless.StatelessContainer.invoke(StatelessContainer.java:191)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.synchronizedBusinessMethod(EjbObjectProxyHandler.java:246)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler.businessMethod(EjbObjectProxyHandler.java:241)
at org.apache.openejb.core.ivm.EjbObjectProxyHandler._invoke(EjbObjectProxyHandler.java:83)
at org.apache.openejb.core.ivm.BaseEjbProxyHandler.invoke(BaseEjbProxyHandler.java:279)
at org.vaadin.saphana.backend.PersistenceFacade$LocalBeanProxy.getAllPersons(org/vaadin/saphana/backend/PersistenceFacade.java)
at org.vaadin.saphana.HanaUI.listEntities(HanaUI.java:134)
at org.vaadin.saphana.HanaUI.init(HanaUI.java:48)
at com.vaadin.ui.UI.doInit(UI.java:646)
at com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:214)
at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:74)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:350)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.sap.core.communication.server.CertValidatorFilter.doFilter(CertValidatorFilter.java:151)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.eclipse.virgo.web.enterprise.security.valve.OpenEjbSecurityInitializationValve.invoke(OpenEjbSecurityInitializationValve.java:44)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at com.sap.core.jpaas.security.auth.service.lib.AbstractAuthenticator.invoke(AbstractAuthenticator.java:205)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at com.sap.core.tenant.valve.TenantValidationValve.invokeNextValve(TenantValidationValve.java:215)
at com.sap.core.tenant.valve.TenantValidationValve.invoke(TenantValidationValve.java:94)
at com.sap.js.statistics.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:25)
at com.sap.core.js.monitoring.tomcat.valve.RequestTracingValve.invoke(RequestTracingValve.java:25)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:812)
I tried with fresh server and it didn't work for me either 🙁 The issue was another mistake I made when refactoring and cleaning the project. DDL settings was incorrect. Just pushed a fix to github that I managed to deploy without issues.
Note to myself: Always test examples with fresh machine and fresh test servers.
Still get the same error 🙁 shame, really would have liked to see it working
Hi, I think you need to delete the old server and create a fresh one. The old server probably contains a database schema that is somehow broken. Or manually drop existing tables before deploying the new version. To verify you get a correctly build war, you could do "mvn clean install" form the parent project.
I also created yet another fix to auto generate proper column types. The default String length appears to be 1 with Hana-Eclipselink combo. This made it pretty hard to insert any sane records.
I hope this helps and thanks for pointing out the demo effects from the demo.
cheers,
matti
Nope, a new server didn't help, i tried with a local derby instance as well, same error. I get the feeling there is eome problems with the schema creation
Did you get the latest updates from the github and "mvn clean install" from the top level (+ new server)?
Here is my test server:
https://hanastinp1941338008trial.hanatrial.ondemand.com/vaadin-ui-0.0.1-SNAPSHOT/
I used the web UI to deploy the application like this:
Hmm, yeah i can see it, but for me it is not working
https://vaadinp769424trial.hanatrial.ondemand.com/vaadin-ui-0.0.1-SNAPSHOT/
I tried once more and guess what, it didn't work for me either! I looked at my stack traces and tracked down the issue to mapping between the DB and the Java EE container.
In "SAP HANA Cloud Platform Cockpit->Databases & Schemas" view I had lots of orphaned DBs (probably due to my todays testing). I tested most of them but I couldn't delete the one with database version "null".
I was able to solve the issue by creating a DB manually on that view and by creating a binding to my Java EE container that failed to start. Then restarted the server and now it seems to work.
I might be wrong, but I think the DB and mapping was automatically handled before (including earlier today). Maybe they are making some updates to the service that caused this issue. If this isn't a temporary hiccup, I guess I'll need to update the instructions.
cheers,
matti
Well, in the cloud i always get the missing widgetset error, localy i get an DB error. Any Ideas how to solve the widgetset problem? it seems to be there, widgetset classes are compiled. In vaadin forums i just found solutions via web.xml which is missing in your projects.