gpt4 book ai didi

hibernate - JPA - 事务未提交

转载 作者:行者123 更新时间:2023-12-02 22:27:01 24 4
gpt4 key购买 nike

我正在开发一个项目,在该项目中我第一次使用 JPA、Hibernate 和所有这些东西,但我遇到了事务未提交的问题。我使用的 User 类如下所示:

 package org.tomasherman.JBTBackup.Resource.Entity;

import javax.persistence.*;
import java.io.Serializable;



@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue
private int id;

private String login;
private String email;
private String password;
private int credit;

public User() {
}

public User(String login, String email, String password, int credit) {
setLogin(login);
setEmail(email);
setPassword(password);
setCredit(credit);
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getLogin() {
return login;
}

public void setLogin(String login) {
this.login = login;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public int getCredit() {
return credit;
}

public void setCredit(int credit) {
this.credit = credit;
}
}

并使用HSQL数据库将其保存在MEMORY表中。 persistence.xml 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<persistence-unit name="JBTBackupPersistance">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>org.tomasherman.JBTBackup.Resource.Entity.User</class>
<properties>
<property name="hibernate.connection.url" value="jdbc:hsqldb:file:./database/database.hsql"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.username" value="SA"/> <!--default hsql login-->
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.archive.autodetection" value="class"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="connection.shutdown" value="true"/>
</properties>
</persistence-unit>

并在 JUnit 测试中对其进行测试,如下所示:

package org.tomasherman.JBTBackup.Resource.Entity;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
* Created by IntelliJ IDEA.
* User: arg
* Date: Jun 29, 2010
* Time: 11:24:35 PM
* To change this template use File | Settings | File Templates.
*/

public class UserTest {
private EntityManagerFactory emf;
private EntityManager em;

private final User u1 = new User("and","now","for",1234);
private final User u2 = new User("something","completely","different",123123123);
private final User u3 = new User("a","man","with",123123123);

@Before
public void initEmfAndEm() {
emf = Persistence.createEntityManagerFactory("JBTBackupPersistance");
em = emf.createEntityManager();
}

@After
public void cleanup() {
em.close();
}

@Test
public void emptyTest() {
System.out.println(em.createQuery("from User").getResultList().size());
if(em.getTransaction().isActive()){
System.out.println("FFfffffffffFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
System.out.println("FFfffffffffFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
System.out.println("FFfffffffffFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
System.out.println("FFfffffffffFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
System.out.println("FFfffffffffFFFFUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU");
}else{
em.getTransaction().begin();
em.persist(u1);
em.persist(u2);
em.persist(u3);
em.getTransaction().commit();
}
System.out.println(em.createQuery("from User").getResultList().size());

}
}

现在的问题是插入通常没有写入数据库。测试的输出如下所示:

    ...some hibernate stuff...
Hibernate:
select
user0_.id as id0_,
user0_.credit as credit0_,
user0_.email as email0_,
user0_.login as login0_,
user0_.password as password0_
from
users user0_
20
Hibernate:
insert
into
users
(id, credit, email, login, password)
values
(null, ?, ?, ?, ?)
Hibernate:
insert
into
users
(id, credit, email, login, password)
values
(null, ?, ?, ?, ?)
Hibernate:
insert
into
users
(id, credit, email, login, password)
values
(null, ?, ?, ?, ?)
Hibernate:
select
user0_.id as id0_,
user0_.credit as credit0_,
user0_.email as email0_,
user0_.login as login0_,
user0_.password as password0_
from
users user0_
23

所以实体在数据库的内存中,但是当我在单元测试后检查数据库时,没有数据。然而,它有时会被提交。

如果有人能帮助我,那就太好了。

编辑:如果它对任何人有帮助,有一个库版本列表(maven 格式):

<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>20040616</version>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.4.0.GA</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
<version>3.1.0.GA</version>
</dependency>
<dependency>
<groupId>hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.0.5</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
</dependency>

更新2:另一个有趣的事情,似乎如果我添加 Thread.sleep(1000);测试结束时,所有事务都会提交。难道程序完成得比数据库更新得更快吗?

最佳答案

根据 HSQLDB 用户指南:

Closing the Database

From version 1.7.2, in-process databases are no longer closed when the last connection to the database is explicitly closed via JDBC [and data are not written to disk], an explicit SHUTDOWN command is required [in order to keep data persistent]. In 1.8.0, a connection property, shutdown=true, can be specified on the first connection to the database (the connection that opens the database) to force a shutdown when the last connection closes.

因此,要么通过 native 查询发送 SHUTDOWN 命令,要么将 ;shutdown=true 添加到连接字符串:

jdbc:hsqldb:file:./database/database.hsql;shutdown=true
<小时/>

关于write_delay的问题,不,将其设置为0不会在单元测试上下文中引起问题(它“只是”对性能产生影响) )。实际上,我希望 shutdown=true 正如文档中所述就足够了:

Application Development and Testing

...

If you do not want to run a Server instance, and you need persistence between tests in different processes, then you should use a file: database. You can use the shutdown=true connection property to ensure the database is persisted fully after the connections are closed. An alternative option is to use hsqldb.write_delay=false connection property, but this is slightly slower than the other option.

It has been reported that some data access frameworks do not close all their connection to the database after the tests. In such situations, you need to use zero WRITE DELAY if you want the data to persist at the end of the tests

但我猜你面临的是第二段中描述的情况。我想知道数据访问层是否真的有罪。

关于hibernate - JPA - 事务未提交,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3207208/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com