使用Play Framework 2.1.x实现多个数据库

16

我有两个需要连接的数据库。我可以在application.conf文件中轻松地连接它们,如下所示:

db.default.driver=org.postgresql.Driver
db.default.url="jdbc:postgresql://localhost/db1"
db.default.user=postgres
db.default.password="password"

db.secondary.driver=org.postgresql.Driver
db.secondary.url="jdbc:postgresql://localhost/db2"
db.secondary.user=postgres
db.secondary.password="password"

ebean.default="models.db1.*"
ebean.secondary="models.db2.*"

我的模型类在这些包中,DDL可以正确生成表。

问题实际上在于处理这些实体。任何不在“默认”包中的内容都会引发此错误(以使用次要数据库中的Users表为例)。

如果我尝试查询表中的所有行:

List<Users> users = Users.find.all();

它会抛出这个错误:

[PersistenceException: models.db2.Users is NOT an Entity Bean registered with this server?]

即使我100%确定用户表存在于后端,它是一个已注册的表,DDL有效并正确地创建了这个表,而且我正在导入正确的类。

我需要以某种特定的方式查询不在默认包中的模型类吗?

编辑:我意识到堆栈跟踪显示它正在尝试使用DefaultServer。我如何使它使用次要服务器?

    at com.avaje.ebeaninternal.server.core.DefaultServer.createQuery(DefaultServer.java:989) ~[avaje-ebeanorm-server.jar:na]
    at com.avaje.ebeaninternal.server.core.DefaultServer.createQuery(DefaultServer.java:946) ~[avaje-ebeanorm-server.jar:na]
    at com.avaje.ebeaninternal.server.core.DefaultServer.find(DefaultServer.java:982) ~[avaje-ebeanorm-server.jar:na]
    at play.db.ebean.Model$Finder.all(Model.java:254) ~[play-java-ebean_2.10.jar:2.1.3]

目前还没有人回答你的问题,所以我认为你应该编辑你的问题,直接问你真正需要的内容,而不是在问题后添加“EDIT:”。 - Greg Kopff
尝试在applications.conf中使用models.db2.Users,而不是models.db2.*。 - Franz
@GregKopff,我只是说“编辑”是因为我不确定是否有人在我编辑问题时回答了它。 - Bert B.
@Franz,我已经尝试过了,但是我得到了一个 Error with [models.db2.Users] It has not been enhanced but it's superClass [class play.db.ebean.Model] is? (You are not allowed to mix enhancement in a single inheritance hierarchy) marker[play.db.ebean.Model] 错误。 - Bert B.
3个回答

7

我遇到了同样的问题,并通过在Model.Finder级别指定服务器名称来解决了它。

因此,在您的情况下,在您的User类中,应该有类似以下内容的代码:

public static Model.Finder<Long, User> find = new Finder<Long, User>("secondary", Long.class, User.class);

哇,这正是我正在寻找的,不幸的是,这只适用于涉及查询此模型的任何内容,但每次我使用保存命令进行此操作时,都会出现错误“类型 ____ 不是已注册的实体?如果您没有明确列出要使用的实体类,则Ebean将在类路径中搜索它们。”你有什么想法如何解决这个问题吗?(是的,我知道我的模型已经正确创建了)。 - Bert B.
抱歉,我不明白。你是如何尝试保存你的对象的?我通常使用 User user = User.find.byId(aId); user.update(aId); user.delete(); 这个方法,它通常能正常工作... - DrMabulle
1
请注意,您还需要告诉Ebean保存方法使用哪个服务器!public void save(String server)。不要使用默认方法save() - myborobudur
Bert B. - 您的配置文件中可能缺少模型包规范,或者在模型类中缺少@Entity注解。 - Rajat

7

好的,你的application.conf文件看起来是正确的。

你可以像这样使用备用服务器:

EbeanServer secondary = Ebean.getServer("secondary");
secondary.find(User.class).findList();

一旦你拥有了备用服务器,你可以像对待Ebean单例一样对待它。


是的,我尝试过这种方法,但问题在于除了实际选择数据之外,还要做其他事情。例如,使用此方法,我可以获取所有用户,但是用户与另一个类“组”具有OneToMany关系。组也在第二个数据库中。在视图中,我想映射每个用户的所有组,因此我有<td>@user.groups.map { group => group.name }</td>,但是它会抛出此错误:[PersistenceException: Query threw SQLException:ERROR: column t1.users_id does not exist ...即使该列确实存在。 - Bert B.

4

您可以同时使用以下两个方式:

public static Model.Finder<Long, User> find = new Finder<Long, User>("secondary", Long.class, User.class);

并且
Ebean.getServer("secondary");

但是您需要在实体中使用服务器声明和保存方法。
public void save(String server)

如果没有使用save(),Ebean将使用默认服务器,即使是在用户实体上也是如此!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接