当前位置: 首页 > 知识库问答 >
问题:

Hibernate级联持续存在:执行孤立工作时出错

微生景胜
2023-03-14

我对Hibernate和SQLite的双向关系有一些问题。实体为:

@Entity
public class Person {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Company company;

    public void setCompany(Company company) {
        this.company = company;
    }
}

和公司:

@Entity
public class Company {

    @Id
    @GeneratedValue
    private Long id;

    @OneToMany(mappedBy = "company", cascade = { CascadeType.PERSIST })
    private Set<Person> staff = new HashSet<>();

    public void addPerson(Person person) {

        if (staff.add(person)) {
            person.setCompany(this);
        }
    }
}

在一个简单的应用程序中,我使用公司创建了一个初始数据库,之后我打开一个新会话来加载公司实例并添加人员。我持久化公司并期望Hibernate在级联中持久化添加的人员。

public class App {

    public static void main(String[] args) {

        createDatabase();

        Session session = createSessionFactory("validate").openSession();

        Company company;

        session.beginTransaction();

        company = (Company) session.createCriteria(Company.class).uniqueResult();
        session.getTransaction().commit();

        company.addPerson(new Person());

        session.beginTransaction();
        session.persist(company);
        session.getTransaction().commit();
    }

    private static void createDatabase() {

        Session session = createSessionFactory("create").openSession();

        Company company = new Company();
        session.beginTransaction();
        session.persist(company);
        session.getTransaction().commit();

        session.close();
    }

    private static SessionFactory createSessionFactory(String ddl) {

        StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder()
            .configure("hibernate.cfg.xml");

        serviceRegistryBuilder
            .applySetting("hibernate.hbm2ddl.auto", ddl);

        SessionFactory sessionFactory = new MetadataSources(serviceRegistryBuilder.build())
            .buildMetadata()
            .buildSessionFactory();

        return sessionFactory;
    }
}

但我错了:

ERROR: database is locked
Exception in thread "main" org.hibernate.exception.GenericJDBCException: error performing isolated work

其中,如果我在添加到公司之前坚持使用该人员(因此没有级联),则应用程序可以工作。

我做错了什么?

以下是完整的应用程序日志:

    июл 29, 2016 9:07:57 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {5.1.0.Final}
июл 29, 2016 9:07:57 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
июл 29, 2016 9:07:57 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
июл 29, 2016 9:07:57 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
июл 29, 2016 9:07:57 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
июл 29, 2016 9:07:57 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [org.sqlite.JDBC] at URL [jdbc:sqlite:default.sqlite]
июл 29, 2016 9:07:57 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=, password=****}
июл 29, 2016 9:07:57 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
июл 29, 2016 9:07:57 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
июл 29, 2016 9:07:57 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.SQLiteDialect
июл 29, 2016 9:07:57 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [2] less than 4
июл 29, 2016 9:07:57 PM org.hibernate.validator.internal.util.Version <clinit>
INFO: HV000001: Hibernate Validator 5.1.0.Final
Hibernate: 
    drop table if exists Company
Hibernate: 
    drop table if exists hibernate_sequence
Hibernate: 
    drop table if exists Person
Hibernate: 
    create table Company (
        id bigint not null,
        primary key (id)
    )
Hibernate: 
    create table hibernate_sequence (
        next_val bigint
    )
Hibernate: 
    insert into hibernate_sequence values ( 1 )
Hibernate: 
    insert into hibernate_sequence values ( 1 )
Hibernate: 
    create table Person (
        id bigint not null,
        company_id bigint,
        primary key (id)
    )
июл 29, 2016 9:07:58 PM org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources
INFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@43f82e78'
Hibernate: 
    select
        next_val as id_val 
    from
        hibernate_sequence
Hibernate: 
    update
        hibernate_sequence 
    set
        next_val= ? 
    where
        next_val=?
Hibernate: 
    insert 
    into
        Company
        (id) 
    values
        (?)
июл 29, 2016 9:07:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)
июл 29, 2016 9:07:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001005: using driver [org.sqlite.JDBC] at URL [jdbc:sqlite:default.sqlite]
июл 29, 2016 9:07:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001001: Connection properties: {user=, password=****}
июл 29, 2016 9:07:59 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH10001003: Autocommit mode: false
июл 29, 2016 9:07:59 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections <init>
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
июл 29, 2016 9:07:59 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.SQLiteDialect
июл 29, 2016 9:07:59 PM org.hibernate.engine.jdbc.env.internal.LobCreatorBuilderImpl useContextualLobCreation
INFO: HHH000423: Disabling contextual LOB creation as JDBC driver reported JDBC version [2] less than 4
Hibernate: 
    select
        this_.id as id1_0_0_ 
    from
        Company this_
Hibernate: 
    select
        personal0_.company_id as company_2_1_0_,
        personal0_.id as id1_1_0_,
        personal0_.id as id1_1_1_,
        personal0_.company_id as company_2_1_1_ 
    from
        Person personal0_ 
    where
        personal0_.company_id=?
Hibernate: 
    select
        next_val as id_val 
    from
        hibernate_sequence
Hibernate: 
    update
        hibernate_sequence 
    set
        next_val= ? 
    where
        next_val=?
июл 29, 2016 9:08:02 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 0, SQLState: null
июл 29, 2016 9:08:02 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: database is locked
Exception in thread "main" org.hibernate.exception.GenericJDBCException: error performing isolated work
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:79)
    at org.hibernate.id.enhanced.TableStructure$1.getNextValue(TableStructure.java:125)
    at org.hibernate.id.enhanced.NoopOptimizer.generate(NoopOptimizer.java:40)
    at org.hibernate.id.enhanced.SequenceStyleGenerator.generate(SequenceStyleGenerator.java:412)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:105)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:768)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:761)
    at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:297)
    at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:391)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:316)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
    at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:424)
    at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:356)
    at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:319)
    at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:155)
    at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:104)
    at org.hibernate.event.internal.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:445)
    at org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:172)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsPersistent(DefaultPersistEventListener.java:164)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:128)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:778)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:751)
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:756)
    at my.tests.hibernate.App.main(App.java:29)
Caused by: java.sql.SQLException: database is locked
    at org.sqlite.core.DB.throwex(DB.java:859)
    at org.sqlite.core.DB.exec(DB.java:142)
    at org.sqlite.jdbc3.JDBC3Connection.commit(JDBC3Connection.java:165)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:60)
    ... 26 more

Upd似乎是一个Hibernate SQLite问题,因为如果我更改H2上的数据库,一切都正常。

共有1个答案

昌博易
2023-03-14

您可以尝试添加策略,以生成id:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
 类似资料:
  • 我有两个JPA实体(账户和个人),具有双向关系: 当我持久化一个人时,我不想持久化所有帐户,但当我持久一个帐户时,我想更新Person属性hasAccounts,因此我还需要更新这个人。 我做了以下步骤: 创建人员 坚持该人 创建帐户 修改所有者(以前创建的 持久帐户(我希望它会自动合并该人) 我得到了这个例外: (我用JPA 1.0配合Hibernate)。

  • 执行获取HQL查询时出现异常。查询大部分时间都有效,但有时会显示此异常 数据库是MySQL,使用的服务器是JBoss 5.1.0 GA 显示的错误是: 组织。冬眠例外GenericJDBCException:无法在组织上执行查询。冬眠例外SQLStateConverter。在组织中处理非特定异常(SQLStateConverter.java:126)。冬眠例外SQLStateConverter。o

  • 我试图在类别和发布类(OneToMany)之间建立关系,我需要删除所有属于特定类别的发布。我不知道我是否遗漏了一些注释,但这是我在执行查询时的错误: org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常org.hibernate.exception.ConstraintViolationException:无法执行更新查询o

  • 子类: 我将它保存在我的DAO中,如下所示: 当我试图保存对象ship,它会给我以下错误:

  • 我正在写一个程序,显示如下所示的航班信息: 我的问题是使用方法时: 当正常运行时,由于某种原因它不会执行,但是当我使用调试器执行程序时,一切都执行得很好,我得到了一个有意义的输出(格式不是很好,但我可以使用),为什么会发生这种情况? 输出应该是这样的: 当我正常运行时,我会得到这个: 这是当我一步虽然(或运行调试): 我希望输出的是单步执行部分(稍后我将处理格式化) eddit:我已经在错误流中添

  • 让我澄清一下我对二级缓存的理解。在我的web应用程序的基类中有一个查询。几乎每一个操作都会调用此查询(我使用的是Struts,这就是应用程序的设计方式,因此不会真正弄乱它),例如,加载我的主页会调用三个单独的Struts操作,并为每个操作执行此查询。QueryDsl形式的查询看起来像