SAP HANA support

60 views
Skip to first unread message

Jonathan Bregler

unread,
Oct 4, 2018, 6:14:18 AM10/4/18
to Ebean ORM
Hi,

Since Ebean doesn't support SAP HANA yet, I'm thinking about implementing and contributing the HANA support. Would you be willing to accept such a contribution?

Thanks,
Jonathan

Rob Bygrave

unread,
Oct 4, 2018, 6:43:46 AM10/4/18
to ebean@googlegroups
Yup !!

--

---
You received this message because you are subscribed to the Google Groups "Ebean ORM" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ebean+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jonathan Bregler

unread,
Oct 4, 2018, 11:01:07 AM10/4/18
to Ebean ORM
Great.

I've created a PR for adding HANA as a platform to ebean-annotation: https://github.com/ebean-orm/ebean-annotation/pull/25.

The rest will follow soon.

Rob Bygrave

unread,
Oct 4, 2018, 4:19:15 PM10/4/18
to ebean@googlegroups
Merged and released as ebean-annotation 4.3 ... should be in maven central shortly.


As a side note, there are the 2 projects ebean-test-config and ebean-test-docker.  We have these to automatically start and configure Postgres, Postgres + PostGIS, MySql, Oracle, SQL Server ( + ElasticSearch).  Ideally we would add in support for Hana but it looks a bit more interesting (more steps) than the others we support right now.


Cheers, Rob.

Jonathan Bregler

unread,
Oct 12, 2018, 3:19:39 AM10/12/18
to Ebean ORM
Hi Rob,

thanks for merging it so quickly.

I looked into ebean-test-config and ebean-test-docker and I think I can add HANA support there as well. I'll let you know when I'm ready.

One issue I came across while trying to run the tests is that in the generated DDL scripts some columns are indexed twice, e.g.:

create index ix_ec_person_phone_owner_id on ec_person_phone (owner_id);
alter table ec_person_phone add constraint fk_ec_person_phone_owner_id
foreign key
(owner_id) references ec_person (id) on delete restrict on
update restrict
;

create index ix_ec_person_phone_ec_person on ec_person_phone
(owner_id);
alter table ec_person_phone add constraint fk_ec_person_phone_ec_person
foreign key
(owner_id) references ec_person (id) on delete restrict on
update restrict
;

This is a problem on HANA, because indexing one column twice is not supported. Is that behavior intentional?

Thanks,
Jonathan

Rob Bygrave

unread,
Oct 12, 2018, 3:55:00 AM10/12/18
to ebean@googlegroups
> Is that behavior intentional?

No, that would be a bug or error ... we should not be indexing the same column twice no.

Jonathan Bregler

unread,
Oct 12, 2018, 4:43:07 AM10/12/18
to Ebean ORM
Ok. Should I open an issue for that?

Rob Bygrave

unread,
Oct 12, 2018, 7:06:16 AM10/12/18
to ebean@googlegroups

I'll have a look ...

Cheers, Rob.

Jonathan Bregler

unread,
Oct 15, 2018, 8:29:22 AM10/15/18
to Ebean ORM
Thanks for fixing it so quickly. I can now get past the DDL generation step.

While running the tests I think I found another issue related to auto-generated columns. Using a SQL statement to extract the generated values instead of Statement.getGeneratedKeys() doesn't work if a draft table is used. The SQL statement always references the non-draft table, so it doesn't return anything after an insert into a draft table which eventually leads to an exception to be thrown in InsertHandler.setGeneratedKey().

javax.persistence.PersistenceException: Autoincrement getGeneratedKeys() returned no rows?
    at io
.ebeaninternal.server.persist.dml.InsertHandler.setGeneratedKey(InsertHandler.java:160)
    at io
.ebeaninternal.server.persist.dml.InsertHandler.fetchGeneratedKeyUsingSelect(InsertHandler.java:177)
    at io
.ebeaninternal.server.persist.dml.InsertHandler.execute(InsertHandler.java:132)
    at io
.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:73)
    at io
.ebeaninternal.server.persist.dml.DmlBeanPersister.insert(DmlBeanPersister.java:49)
    at io
.ebeaninternal.server.core.PersistRequestBean.executeInsert(PersistRequestBean.java:1232)
    at io
.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:780)
    at io
.ebeaninternal.server.core.PersistRequestBean.executeNoBatch(PersistRequestBean.java:835)
    at io
.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:826)
    at io
.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:503)
    at io
.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:451)
    at io
.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:438)
    at io
.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1720)
    at io
.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1712)
    at io
.ebean.Model.save(Model.java:190)
    at org
.tests.transaction.TestTransactionTryResources.tryWithResources_catch(TestTransactionTryResources.java:52)
    at sun
.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun
.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun
.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java
.lang.reflect.Method.invoke(Method.java:498)
    at org
.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org
.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org
.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org
.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org
.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org
.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at io
.ebean.ConditionalTestRunner.runChild(ConditionalTestRunner.java:33)
    at io
.ebean.ConditionalTestRunner.runChild(ConditionalTestRunner.java:16)
    at org
.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org
.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org
.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org
.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org
.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org
.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org
.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org
.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org
.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
    at org
.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org
.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org
.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)



Thanks,
Jonathan

Rob Bygrave

unread,
Oct 18, 2018, 4:19:50 PM10/18/18
to eb...@googlegroups.com
Yes ok, I'll have a look sometime shortly.

Thanks, Rob.

Rob Bygrave

unread,
Oct 18, 2018, 10:58:24 PM10/18/18
to ebean@googlegroups

Jonathan Bregler

unread,
Oct 23, 2018, 7:11:00 AM10/23/18
to Ebean ORM
Thanks again for fixing it.

I've created a PR for the HANA changes: https://github.com/ebean-orm/ebean/pull/1511

Let me know if you need me to make any changes.

I'm still working on the changes for ebean-test-config and ebean-test-docker. I'll keep you posted.

- Jonathan

Rob Bygrave

unread,
Oct 24, 2018, 4:55:32 AM10/24/18
to ebean@googlegroups
Excellent work. I've merged in that PR.

> I'm still working on the changes for ebean-test-config and ebean-test-docker. I'll keep you posted.

Yup, cool.  It is pretty nice to have a nice test setup using docker. I'm always using ebean-test-config & docker now (except in building/testing Ebean itself which is a bit ironic).


Cheers, Rob.

Jonathan Bregler

unread,
Nov 14, 2018, 12:11:11 PM11/14/18
to Ebean ORM
I've created the PRs for the testing projects:


Basically for HANA you need to create an external directory, put a JSON file containing a master password inside it, and agree to the license. I've created the properties hana.mountsDirectory, hana.passwordsUrl, and hana.agreeToSapLicense, respectively, to pass the information to Ebean. If everything is setup correctly, the HANA docker container can be started automatically. The manual process to get the docker container running is also described here: https://developers.sap.com/tutorials/hxe-ua-install-using-docker.html

Let me know what you think.

Best,
Jonathan

Rob Bygrave

unread,
Nov 30, 2018, 3:30:18 AM11/30/18
to ebean@googlegroups
BTW: Thanks Jonathan for doing this.  Makes it easy to play around with Hana etc which is great.

Cheers, Rob.
Reply all
Reply to author
Forward
0 new messages