I have for the last three months been working on a new playframework 2.4 application that uses h2 in dev and postgres on the server. We are using ebean as the ORM and java 8 as development language, and I've generally been happy with that experience.
One of the requirements of the application is to store some data in an external mysql database.
So I added the database to my application.conf:
db.quba.driver = com.mysql.jdbc.Driver
db.quba.url = "jdbc:mysql://localhost:3306/quba"
db.quba.username = "..."
db.quba.password = "..."
Set the migrations for that db to off:
play.evolutions.db.quba.enabled = false
Added the ebean config:
ebean.quba= "quba.models.*"
Created the models:
package quba.models;
import javax.persistence.*;
import com.avaje.ebean.Expr;
import com.avaje.ebean.Model;
@Entity
@Table(name = "st_profile")
public class QubaStationProfile extends Model {
public static Model.Finder<Long, QubaStationProfile> find = new Model.Finder<>("quba",QubaStationProfile.class);
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "stationid")
public Long id;
public Integer session;
public String profiles;
public String exception;
public String site;
public static QubaStationProfile findStProfileByStationAndTermin(Long stationid, int termin) {
return QubaStationProfile.find.where()
.conjunction()
.add(Expr.eq("stationid", stationid))
.add(Expr.eq("session", termin))
.findUnique();
}
}
And implemented the service that uses the models.
My issue is that altough I can use the model for querying the database using the finder method, as soon as I try to save() an entity I get the following error message:
javax.persistence.PersistenceException: The type [class quba.models.QubaStation] is not a registered entity? If you don't explicitly list the entity classes to use Ebean will search for them in the classpath.
If the entity is in a Jar check the ebean.search.jars property in ebean.properties file or check ServerConfig.addJar().
at com.avaje.ebeaninternal.server.persist.DefaultPersister.createRequest(DefaultPersister.java:1189) ~[avaje-ebeanorm-4.6.2.jar:na]
I have added
playEbeanDebugLevel := 9
to my build.sbt and verified that the classes in quba.models.* are indeed being picked up and instrumented by the by the ebean sbt agent.
ebean-enhance> cls: quba/models/QubaStation msg: already enhanced entity
ebean-enhance> cls: quba/models/QubaStation msg: no enhancement on class
I have also verified that the mysql user can access the database and has privilege to create and update records in that database.
Here is a failing test case
package models;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import play.test.FakeApplication;
import play.test.Helpers;
import quba.models.QubaStation;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
public class QubaStationModelTest {
public FakeApplication app;
@Test
public void testCreateStation(){
QubaStation station = new QubaStation();
station.name ="X";
station.latitude = 1;
station.longitude = 2;
station.save();
station = QubaStation.findStationByName("X");
assertNotNull(station);
assertEquals("","X",station.name);
station.delete();
}
@Before
public void before() {
Map<String, String> mysql = new HashMap<>();
mysql.put("db.quba.driver","com.mysql.jdbc.Driver");
mysql.put("db.quba.url","jdbc:mysql://localhost:3306/quba");
mysql.put("db.quba.username","...");
mysql.put("db.quba.password","...");
app = Helpers.fakeApplication(mysql);
Helpers.start(app);
}
@After
public void after() {
Helpers.stop(app);
}
}
The test output:
[error] Test models.QubaStationModelTest.testCreateStation failed: javax.persistence.PersistenceException: The type [class quba.models.QubaStation] is not a registered entity? If you don't explicitly list the entity classes to use Ebean will search for them in the classpath. If the entity is in a Jar check the ebean.search.jars property in ebean.properties file or check ServerConfig.addJar()., took 3.608 sec
[error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.createRequest(DefaultPersister.java:1189)
[error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:208)
[error] at com.avaje.ebeaninternal.server.persist.DefaultPersister.save(DefaultPersister.java:199)
[error] at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1461)
[error] at com.avaje.ebeaninternal.server.core.DefaultServer.save(DefaultServer.java:1454)
[error] at com.avaje.ebean.Model.save(Model.java:208)
[error] at models.QubaStationModelTest.testCreateStation(QubaStationModelTest.java:26)
Any help on resolving this issue will be highly appreciated.
Update:
I also tried the new list syntax
ebean.quba= ["quba.models.*"]
as well as enumerating the individual model classes:
ebean.quba= ["quba.models.QubaStationProfile","quba.models.QubaStation"]
, but that made no difference.
Also note that I am not using the "default" server. I use
play.ebean.defaultDatasource=h2
during development, which is overridden in the server config using
play.ebean.defaultDatasource=postgres
I have also noticed, that even though evolutions are disabled for quba, play nevertheless created the evolution scripts. This may, or may not be relevant for this issue.
UPDATE:
I have determined that play-ebean is using the 'postgres' serverConfig when trying to save the object that belongs in the 'quba' database. Since the BeanDescriptorManager for 'postgres' does not contain any of the BeanDescriptors for the 'quba' database, it fails.