EntityManager 不写入数据库
我刚刚建立了一个到目前为止仍然相当小的项目 maven/jpa/hibernate 项目,我试图在其中保留一个对象。
我的类是一个非常简单的类:
@Entity
public class Person {
@Id @GeneratedValue
private int id;
private String name;
}
我的 persistence.xml 也非常基本:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="Fahrplan_v2">
<class>model.Person</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:file:data/db/db" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
最后,这是我用来持久化对象的代码:
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.persist(person);
// em.flush(); <- does not effect outcome.
em.getTransaction().commit();
em.close();
现在我希望这里发生两件事:首先,我希望 Person 表要创建(由于 hibernate.hbm2ddl.auto=update)。这种情况发生过一次,并且它正确地写出来了,
CREATE MEMORY TABLE PUBLIC.PERSON(
ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
NAME VARCHAR(255)
)
但我根本无法重现。每次我启动程序时,都会创建 hsqldb 数据库文件,但不会创建表。
其次,我希望持久化对象存储在数据库中,但事实并非如此。此外,手动创建数据库模式并不能解决问题,因此这不是导致问题的原因。持久代码运行时没有任何异常或输出中出现任何警告,一切看起来都很好。但该对象只是没有到达数据库。使用“from Person”查询实体管理器时也找不到该对象。
然而,查询似乎是唯一有效的方法。我可以手动将数据插入数据库,“from Person”查询将成功检索它。
那么,关于我在这里做错了什么的任何提示吗?
i just set up a so far still quite minimal project maven/jpa/hibernate project, where i am trying to persist an object.
My class is a quite simple one:
@Entity
public class Person {
@Id @GeneratedValue
private int id;
private String name;
}
My persistence.xml is very basic as well:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="Fahrplan_v2">
<class>model.Person</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" />
<property name="hibernate.connection.url" value="jdbc:hsqldb:file:data/db/db" />
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
</properties>
</persistence-unit>
</persistence>
And lastly here's the code i use to persist the object:
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();
em.persist(person);
// em.flush(); <- does not effect outcome.
em.getTransaction().commit();
em.close();
Now there's two things i would expect to happen here: First, i'd expect the Person table to be created (due to hibernate.hbm2ddl.auto=update). This has happened once, and it correctly wrote out
CREATE MEMORY TABLE PUBLIC.PERSON(
ID INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 1) NOT NULL PRIMARY KEY,
NAME VARCHAR(255)
)
but i can't reproduce that at all. Every time i start my program, the hsqldb database files get created, but no tables are created.
Second, i would expect the persisted object to be stored in the database, but it is not. Also, manually creating the database schema doesn't solve the problem, so that's not what's causing it. The persisting code runs without any exceptions or any warnings in the output, it all looks perfectly fine. But the object just does not arrive in the database. The object is also not found when querying the entity manager with a "from Person".
The querying however seems to be the only thing that DOES work. i can manually insert a datum into the database and the "from Person" query will successfully retrieve it.
so, any hints on what i am doing wrong here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
添加 axtavt 的好答案并澄清您的 sleep(1000) 是如何工作的:对于您想要绝对同步持久性的开发情况,请关闭默认的 write_delay。
这意味着每个语句在结果返回给调用者之前都会写入磁盘。当然,在正常操作时,你可以增加这个值。默认是500毫秒,需要sleep(1000)。给出的信息适用于 HSQLDB 版本 2.2.x。
Adding to the good answer by axtavt and clarifying how your sleep(1000) worked: For development situations where you want absolutely synchronous persistence, turn off the default write_delay.
This means every statement is written to disk before the result is returned to the caller. Naturally, in normal operation, you can increase this value. The default is 500 ms, which needs the sleep(1000). The information given is for HSQLDB version 2.2.x.
您需要将
shutdown=true
添加到数据库 URL(或发出显式SHUTDOWN
命令),以便正确关闭进程内 HSQLDB 数据库:参见另外:
You need to add
shutdown=true
to the database URL (or issue an explictSHUTDOWN
command) in order to correctly shut down an in-process HSQLDB database:See also:
希望这对某人有帮助。将写入延迟设置为 0 毫秒的建议可行,但除非您创建新的数据库,否则它不会从 url 起作用。要应用它,请在连接到数据库时使用下面的 sql 语句在脚本中运行它:
例如,您可以使用 sqltool.jar 运行它,如下所示:
Hope this helps someone. The suggestion to set the write delay to 0 ms works, but it does not work from the url unless you're creating a new db. To have it apply, run it in a script while connected to the database using the sql statement below:
So for example, you can run it using the sqltool.jar like so: