I'm brand new with Play Framework
and with Ebean
. I need to configure a Play application to use two different database instances, one for reading and another for writing. I have been looking in it seems that this is a recurrent issue and I've tried all the possible solutions that I've been able to find, even the once that works for somebody and isn't working for me, for sure I'm doing something wrong, because the error has to do or looks like with the classloader
.
build.sbt
lazy val root = (project in file(".")).enablePlugins(PlayJava, PlayEbean)
val playEbean = "6.0.0"
libraryDependencies ++= Seq(
...
"com.typesafe.play" % "play-ebean_2.13" % playEbean,
...
application.conf
db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://localhost:5432/db_writer"
db.default.username=username
db.default.password=pass
db.reader.driver=org.postgresql.Driver
db.reader.url="jdbc:postgresql://localhost:5432/db_reader"
db.reader.username=username
db.reader.password=pass
ebean.default = ["models.db_writer.*"]
ebean.reader = ["models.db_reader.*"]
play.ebean.defaultDatasource = "db_writer"
EbeanServerReader
import io.ebean.Ebean;
import io.ebean.EbeanServer;
public class EbeanServerReader {
public static EbeanServer getReader() {
return Ebean.getServer("reader");
}
}
myDaoClass
public class myDaoClass {
private final FetchConfig fetchConfig = new FetchConfig();
private final EbeanServer reader = EbeanServerReader.getReader();
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public PagedList<SomeClass> findAllWithNoLimit(int pageIndex, int pageSize, String type) {
return reader.find(SomeClass.class)
.fetch("path", fetchConfig.lazy(100))
.fetch("path", fetchConfig.lazy(100))
.fetch("path", fetchConfig.lazy(100))
.where()
.eq("propertyName", type)
.order()
.desc("updatedAt")
.setFirstRow(pageIndex * pageSize)
.setMaxRows(pageSize)
.findPagedList();
}
Error trace:
1) Error injecting constructor, java.lang.NoClassDefFoundError: Could not initialize class io.ebean.Ebean
at models.myDaoClass.<init>(myDaoClass.java:12)
while locating models.myDaoClass
for the 1st parameter of models.myDaoClass.<init>(myDaoClass.java:33)
while locating models.myDaoClass
1 error
at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:226)
at com.google.inject.internal.InjectorImpl$1.get(InjectorImpl.java:1097)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1131)
at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:436)
at play.api.inject.guice.GuiceInjector.instanceOf(GuiceInjectorBuilder.scala:431)
at play.api.inject.ContextClassLoaderInjector.$anonfun$instanceOf$2(Injector.scala:119)
at play.api.inject.ContextClassLoaderInjector.withContext(Injector.scala:128)
at play.api.inject.ContextClassLoaderInjector.instanceOf(Injector.scala:119)
at play.api.libs.concurrent.ActorRefProvider.$anonfun$get$1(Akka.scala:268)
at akka.actor.TypedCreatorFunctionConsumer.produce(IndirectActorProducer.scala:91)
at akka.actor.Props.newActor(Props.scala:226)
at akka.actor.ActorCell.newActor(ActorCell.scala:613)
at akka.actor.ActorCell.create(ActorCell.scala:640)
... 9 common frames omitted
Caused by: java.lang.NoClassDefFoundError: Could not initialize class io.ebean.Ebean
at module.EbeanServerReader.getReader(EbeanServerReader.java:8)
What am I doing wrong here? I've try another stuffs, like @Inject
but is the same.
Kind regards
Problem solved by replacing:
ebean.default = ["models.db_writer.*"]
ebean.reader = ["models.db_reader.*"]
with this:
ebean.default = ["models.*"]
ebean.writer = ["models.*"]
as my application uses the same class model
just different db
instances, one for reading and another for writing.