H2 数据库在 playframework2 中失败

Posted

技术标签:

【中文标题】H2 数据库在 playframework2 中失败【英文标题】:H2 database fail in playframework2 【发布时间】:2012-06-25 08:24:13 【问题描述】:

我使用 play 2.0.1 开发小型应用程序,发现使用内部 H2 数据库进行客户预览非常有用。数据库中只有几行和一两个用户。在我的笔记本电脑中编译应用程序并制作 tar 以部署在测试服务器上非常方便。但看起来 H2 有时会下降。我在我的 application.log 中找到了这个:

! @6anj14ljo - 内部服务器错误,请求 [POST /admin] ->

play.core.ActionInvoker$$anonfun$receive$1$$anon$1:执行 异常 [[PersistenceException: 查询抛出 SQLException:table 未找到“经理”。

我知道使用 H2 进行生产不是一个好主意。但是我不想每次都配置mysql。 这种 H2 行为的原因是什么?

【问题讨论】:

我不知道可能是什么问题。你能提供一个可重现的测试用例吗?见sscce.org 很难提供测试用例。原因是我有几个小应用程序,它们都是不同的,但有时它们都在预生产模式下无法访问数据库(预生产意味着做play clean compile阶段,但是嵌入了inmemmory H2)这不是问题我可以通过动作序列重现。它们刚刚发生,我找不到任何原因。 你使用eclipse作为你的编辑器吗?我发现,如果我有时在进行更改时打开 Eclipse,我会在 h2 中遇到这些错误。我发现我可以保证让它工作的唯一方法是关闭日食。关闭播放并运行“干净”、“更新”然后“运行”。 【参考方案1】:

使用h2-browser 检查数据库的状态,以及结构是否与异常相同:

在终端/命令行中

    play h2-browser - 它将在新的浏览器窗口中打开 h2-browser ~run 进行演进 转到带有h2-browser 的窗口,并使用与application.confdb.default.url 中提供的相同路径进行连接

另一方面,与您相反,我发现在开发和生产模式中使用不同的数据库可能很烦人。每个数据库引擎都有一些非常具体的问题,您需要解决一些问题两次,一次用于H2 - 稍后用于MySQL。这没有任何意义,更糟糕的是,每次在开发模式下重新启动应用程序时,都需要再次填充样本数据以进行调试。也许在重新启动之间你忘了添加一些记录等。

虽然最后一个问题可以通过在onStart() 方法中插入与Global object 相同的一组测试数据来解决,但在重启之间将测试数据保留在MySQL 中会更舒服。

当然,如果您仍然想要/需要使用H2,您也可以在file mode 中使用它,方法是从url 中删除mem 段,然后它将被持久化在磁盘上。

【讨论】:

可以编译应用吗?我没有在测试服务器上安装游戏。无论如何,尝试文件模式是个好主意。我完全失去了它。 可能是的,但你需要检查一下,我在生产中使用 MySQL,所以我不知道它如何与文件内 h2 一起工作。无论如何,如果您要检查它,请告诉我。 看起来没有办法启动嵌入式 h2 的 web 界面。也许项目内代码中的一些技巧可以提供帮助。但这是个坏主意。 什么意思?我不明白,也许在单独的问题中描述问题? 这很棒,不知道h2-browser。谢谢!【参考方案2】:

您是否将数据库配置为在没有连接的情况下不删除表?从documentation 开始,它表示您必须在配置文件中将DB_CLOSE_DELAY=-1 附加到您的数据库 url 以防止此类行为。

当我在 docker 容器中运行带有内存数据库的“生产”应用程序时,我遇到了与您相同的错误。在我运行它而不与它交互一段时间后,这些表将被删除。

附加DB_CLOSE_DELAY=-1 标志似乎已修复它

【讨论】:

以上是关于H2 数据库在 playframework2 中失败的主要内容,如果未能解决你的问题,请参考以下文章

Play framework 2.0.1 不断尝试进化错误的数据库类型

使用 @IdClass 的 JPA 多对多与额外列在 springTestContextPreparation Hibernate AnnotationException“没有持久的 id 属性”中失

本地和原始存储库 git 之间没有区别。但是当其他人克隆项目时,在 H2DB 中找不到该表?

如何在 playframework 2.0 中配置 FS 数据库?

Play framework 2.0 尝试级联删除时出错“参数“#1”未设置;SQL语句:delete”

React - 判断焦点是否在某个元素上