EntityManager 不写入数据库

发布于 2024-12-15 07:05:55 字数 2080 浏览 3 评论 0原文

我刚刚建立了一个到目前为止仍然相当小的项目 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅浅 2024-12-22 07:05:55

添加 axtavt 的好答案并澄清您的 sleep(1000) 是如何工作的:对于您想要绝对同步持久性的开发情况,请关闭默认的 write_delay。

 <property name="hibernate.connection.url" 
      value="jdbc:hsqldb:file:data/db/db;shutdown=true;hsqldb.write_delay_millis=0"/>             

这意味着每个语句在结果返回给调用者之前都会写入磁盘。当然,在正常操作时,你可以增加这个值。默认是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.

 <property name="hibernate.connection.url" 
      value="jdbc:hsqldb:file:data/db/db;shutdown=true;hsqldb.write_delay_millis=0"/>             

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.

能否归途做我良人 2024-12-22 07:05:55

您需要将 shutdown=true 添加到数据库 URL(或发出显式 SHUTDOWN 命令),以便正确关闭进程内 HSQLDB 数据库:

<property name="hibernate.connection.url" 
     value="jdbc:hsqldb:file:data/db/db;shutdown=true" />             

参见另外:

You need to add shutdown=true to the database URL (or issue an explict SHUTDOWN command) in order to correctly shut down an in-process HSQLDB database:

<property name="hibernate.connection.url" 
     value="jdbc:hsqldb:file:data/db/db;shutdown=true" />             

See also:

站稳脚跟 2024-12-22 07:05:55

希望这对某人有帮助。将写入延迟设置为 0 毫秒的建议可行,但除非您创建新的数据库,否则它不会从 url 起作用。要应用它,请在连接到数据库时使用下面的 sql 语句在脚本中运行它:

set files write delay false

例如,您可以使用 sqltool.jar 运行它,如下所示:

java -jar /path/to/sqltool.jar -sql "set files write delay false;" --inlinerc=<rc spec here>

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:

set files write delay false

So for example, you can run it using the sqltool.jar like so:

java -jar /path/to/sqltool.jar -sql "set files write delay false;" --inlinerc=<rc spec here>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文