Exception with Ebean @OneToMany relation with custom table name

Hi there,

An example is worth a thousand words…
So here is the repo GitHub with the error: GitHub - Flo354/test_play_ebean_onetomany_fails

I have Three tables: BaseWebsite, Website and Domain (in models package)
BaseWebsite has a custom name: “website”
Website class extends BaseWebsite with InheritanceType.SINGLE_TABLE.
One BaseWebsite (so Website also) can have multiple domains.
On my table BaseWebsite, I have a @OneToMany relation for the list of Domain.

The problem is that when I am trying to get the domains, I have an exception:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[PersistenceException: Query threw SQLException:Unknown column ‘t0.base_website_id’ in ‘field list’ Bind values: Query was:select t0.base_website_id, t0.website_id, t0.domain, t1.type, t0.website_id from domain t0 left join website t1 on t1.id = t0.website_id and t1.type = ‘a’ where (t0.base_website_id) in (? ) ]]
at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:251)
at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:178)
at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:363)
at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:361)
at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:413)
at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:37)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
at scala.concurrent.BlockContext$.withBlockContext(BlockContext.scala:81)
at akka.dispatch.BatchingExecutor$BlockableBatch.run(BatchingExecutor.scala:91)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(ForkJoinExecutorConfigurator.scala:44)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: javax.persistence.PersistenceException: Query threw SQLException:Unknown column ‘t0.base_website_id’ in ‘field list’ Bind values: Query was:select t0.base_website_id, t0.website_id, t0.domain, t1.type, t0.website_id from domain t0 left join website t1 on t1.id = t0.website_id and t1.type = ‘a’ where (t0.base_website_id) in (? )
at io.ebean.config.dbplatform.SqlCodeTranslator.translate(SqlCodeTranslator.java:52)
at io.ebean.config.dbplatform.DatabasePlatform.translate(DatabasePlatform.java:211)
at io.ebeaninternal.server.query.CQueryEngine.translate(CQueryEngine.java:141)
at io.ebeaninternal.server.query.DefaultOrmQueryEngine.translate(DefaultOrmQueryEngine.java:45)
at io.ebeaninternal.server.core.OrmQueryRequest.translate(OrmQueryRequest.java:97)
at io.ebeaninternal.server.query.CQuery.createPersistenceException(CQuery.java:700)
at io.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:399)
at io.ebeaninternal.server.query.DefaultOrmQueryEngine.findMany(DefaultOrmQueryEngine.java:156)
at io.ebeaninternal.server.core.OrmQueryRequest.findList(OrmQueryRequest.java:442)
at io.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1516)
at io.ebeaninternal.server.core.DefaultServer.findList(DefaultServer.java:1494)
at io.ebeaninternal.server.core.DefaultBeanLoader.executeQuery(DefaultBeanLoader.java:223)
at io.ebeaninternal.server.core.DefaultBeanLoader.loadMany(DefaultBeanLoader.java:87)
at io.ebeaninternal.server.core.DefaultServer.loadMany(DefaultServer.java:523)
at io.ebeaninternal.server.loadcontext.DLoadManyContext$LoadBuffer.loadMany(DLoadManyContext.java:229)
at io.ebean.common.AbstractBeanCollection.lazyLoadCollection(AbstractBeanCollection.java:98)
at io.ebean.common.BeanList.init(BeanList.java:135)
at io.ebean.common.BeanList.iterator(BeanList.java:329)
at java.lang.Iterable.forEach(Iterable.java:74)
at controllers.DefaultController.fail(DefaultController.java:18)
at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$4(Routes.scala:95)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:134)
at play.core.routing.HandlerInvokerFactory$$anon$3.resultCall(HandlerInvoker.scala:133)
at play.core.routing.HandlerInvokerFactory$JavaActionInvokerFactory$$anon$8$$anon$2$$anon$1.invocation(HandlerInvoker.scala:108)
at play.core.j.JavaAction$$anon$1.call(JavaAction.scala:88)
at play.http.DefaultActionCreator$1.call(DefaultActionCreator.java:31)
at play.core.j.JavaAction.$anonfun$apply$8(JavaAction.scala:138)
at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:654)
at scala.util.Success.$anonfun$map$1(Try.scala:251)
at scala.util.Success.map(Try.scala:209)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:288)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)
at play.core.j.HttpExecutionContext$$anon$2.run(HttpExecutionContext.scala:56)
at play.api.libs.streams.Execution$trampoline$.execute(Execution.scala:70)
at play.core.j.HttpExecutionContext.execute(HttpExecutionContext.scala:48)
at scala.concurrent.impl.CallbackRunnable.executeWithValue(Promise.scala:68)
at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete(Promise.scala:368)
at scala.concurrent.impl.Promise$KeptPromise$Kept.onComplete$(Promise.scala:367)
at scala.concurrent.impl.Promise$KeptPromise$Successful.onComplete(Promise.scala:375)
at scala.concurrent.impl.Promise.transform(Promise.scala:29)
at scala.concurrent.impl.Promise.transform$(Promise.scala:27)
at scala.concurrent.impl.Promise$KeptPromise$Successful.transform(Promise.scala:375)
at scala.concurrent.Future.map(Future.scala:288)
at scala.concurrent.Future.map$(Future.scala:288)
at scala.concurrent.impl.Promise$KeptPromise$Successful.map(Promise.scala:375)
at scala.concurrent.Future$.apply(Future.scala:654)
at play.core.j.JavaAction.apply(JavaAction.scala:138)
at play.api.mvc.Action.$anonfun$apply$2(Action.scala:96)
at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$4(Accumulator.scala:174)
at scala.util.Try$.apply(Try.scala:209)
at play.api.libs.streams.StrictAccumulator.$anonfun$mapFuture$3(Accumulator.scala:174)
at scala.Function1.$anonfun$andThen$1(Function1.scala:52)
at play.api.libs.streams.StrictAccumulator.run(Accumulator.scala:207)
at play.core.server.AkkaHttpServer.$anonfun$runAction$4(AkkaHttpServer.scala:357)
at akka.http.scaladsl.util.FastFuture$.strictTransform$1(FastFuture.scala:41)
at akka.http.scaladsl.util.FastFuture$.$anonfun$transformWith$3(FastFuture.scala:51)
… 12 common frames omitted
Caused by: java.sql.SQLSyntaxErrorException: Unknown column ‘t0.base_website_id’ in ‘field list’
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:975)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1025)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeQuery(HikariProxyPreparedStatement.java)
at io.ebeaninternal.server.query.CQuery.prepareResultSet(CQuery.java:376)
at io.ebeaninternal.server.query.CQuery.prepareBindExecuteQueryWithOption(CQuery.java:324)
at io.ebeaninternal.server.query.CQuery.prepareBindExecuteQuery(CQuery.java:319)
at io.ebeaninternal.server.query.CQueryEngine.findMany(CQueryEngine.java:375)
… 63 common frames omitted

It says that

Unknown column ‘t0.base_website_id’ in ‘field list’ Bind values: Query was:select t0.base_website_id, t0.website_id, t0.domain, t1.type, t0.website_id from domain t0 left join website t1 on t1.id = t0.website_id and t1.type = ‘a’ where (t0.base_website_id) in (? ) ]]

I don’t understand why it searches for base_website_id since I have an annotation on BaseWebsite which is @Table(name=“website”)

In the other hand, I have two classes, Websitea & Domaina which are the same except that there is no base class and it works.

If you want to test with the project on github, when the webserver is launched, just go to hjttp://127.0.0.1:9000/fail to see the exception. Don’t forget in application.conf to set the correct username, password and table name for the line db.development.url.

I am using latest version of play framework 2.6.19 and play ebean 4.1.3.

What am I missing?

Thanks,

Writing the question gave me the idea to manually set the column name. So in BaseWebsite, I added a JoinColumn annotation in addition to the OneToMany annotation.

@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "website_id", referencedColumnName = "id", table = "website")
private List<Domain> domains;

And it works… The question is why I have to do that since I gave the custom table name?