Persistindo dados com jpa + sqlite

Pessoal, estou enfrentando problemas ao tentar persistir dados utilizando jpa + sqlite. Na verdade o primeiro registro é inserido, mas a partir do segundo registro recebo um erro:

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: error performing isolated work
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1152)
	at dao.ClienteDAO.salvar(ClienteDAO.java:24)
	at controller.ClienteController.salvar(ClienteController.java:26)
	at view.ClienteView.jbtSalvarActionPerformed(ClienteView.java:288)
	at view.ClienteView.access$600(ClienteView.java:20)
	at view.ClienteView$6.actionPerformed(ClienteView.java:133)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:289)
	at java.awt.Component.processMouseEvent(Component.java:6533)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6298)
	at java.awt.Container.processEvent(Container.java:2236)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Container.dispatchEventImpl(Container.java:2294)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
	at java.awt.Container.dispatchEventImpl(Container.java:2280)
	at java.awt.Window.dispatchEventImpl(Window.java:2746)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.awt.EventQueue$4.run(EventQueue.java:729)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: 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.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
	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 org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146)
	... 42 more
Caused by: org.sqlite.SQLiteException: [SQLITE_BUSY]  The database file is locked (database is locked)
	at org.sqlite.core.DB.newSQLException(DB.java:909)
	at org.sqlite.core.DB.newSQLException(DB.java:921)
	at org.sqlite.core.DB.throwex(DB.java:886)
	at org.sqlite.core.DB.exec(DB.java:155)
	at org.sqlite.jdbc3.JDBC3Connection.commit(JDBC3Connection.java:174)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:60)
	... 54 more

Já fiz várias pesquisas no fórum e internet e, baseado nestas pesquisa que realizei, não encontrei uma solução.

Posto a seguir minhas classes e desde já agradeço caso algum colega possa me ajudar a resolver este impasse.

package model;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;

/**
 *
 * @author Marcos
 */
@Entity
@NamedQueries({
    @NamedQuery(name = "Cliente.consultarTodos", query = "SELECT c FROM Cliente c WHERE c.nomeCliente LIKE :texto ORDER BY c.nomeCliente"),})
public class Cliente implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int idCliente;

    @Column(columnDefinition = "VARCHAR(255)")
    private String nomeCliente;

    @Column
    private String endereco;

    @Column
    private String cep;

    @Column
    private String telCliente;

    @Column
    private String celCliente;

    @Column
    private String email;

    public Cliente() {
    }

    public int getIdCliente() {
        return idCliente;
    }

    public void setIdCliente(int idCliente) {
        this.idCliente = idCliente;
    }

    public String getNomeCliente() {
        return nomeCliente;
    }

    public void setNomeCliente(String nomeCliente) {
        this.nomeCliente = nomeCliente;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String getCep() {
        return cep;
    }

    public void setCep(String cep) {
        this.cep = cep;
    }

    public String getTelCliente() {
        return telCliente;
    }

    public void setTelCliente(String telCliente) {
        this.telCliente = telCliente;
    }

    public String getCelCliente() {
        return celCliente;
    }

    public void setCelCliente(String celCliente) {
        this.celCliente = celCliente;
    }

    public String getEmail() {
        return email;
    }

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

}


package dao;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import model.Cliente;
import util.FabricaConexao;

/**
 *
 * @author Marcos
 */
public class ClienteDAO {

    public static Cliente salvar(Cliente c) {
        EntityManager em = FabricaConexao.getConexao();
        try {
            em.getTransaction().begin();
            em.persist(c);
            em.getTransaction().commit();
           // em.refresh(c);
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            em.getTransaction().rollback();
            return null;
        } finally {
            em.close();
        }
    }
}


package util;

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

/**
 *
 * @author Marcos
 * Data: 31/03/2018
 */
public class FabricaConexao {
    private static EntityManagerFactory fabrica = null;
    private static EntityManager em = null;
    
    private FabricaConexao() {
        
    }
    
    public static EntityManager getConexao() {
        try {
            if (fabrica == null) {
                fabrica = Persistence.createEntityManagerFactory("Controle_ServicosPU");
            }            
            em = fabrica.createEntityManager();
            return em;
        } catch(Exception e) {
            e.printStackTrace();
            return null;
        }
    }  
    
}

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="Controle_ServicosPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>model.Cliente</class>
        <class>model.OrdemServicoModel</class>
        <shared-cache-mode>NONE</shared-cache-mode>
        <properties>
            <property name="hibernate.dialect" value="util.SQLiteDialect"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:sqlite:bd\mydb.db"/>
            <property name="javax.persistence.jdbc.user" value=""/>
            <property name="javax.persistence.jdbc.driver" value="org.sqlite.JDBC"/>
            <property name="javax.persistence.jdbc.password" value=""/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
            <property name="hibernate.connection.charSet" value="UTF-8" />
        </properties>
    </persistence-unit>
</persistence>

Desde já agradeço a atenção!

Precisa desfazer o lock do banco.

Darlan, como faço isso? Pode me explicar?

Olha, como é o SQLite, eu reinstalaria tudo.
Mas, se tiver dados importantes, talvez isso ajude

Darlan, ainda estou implementando o sistema, logo não há dados importantes e nem o que reinstalar.

A propósito, esse Lock é algo feito pelo sistema operacional ou via código fonte?

Olha, tem algumas razões para um lock ocorrer.

Mais algum colega que possa me dar alguma outra sugestão? Continuo tentando encontrar uma solução no google, mas até agora nada.

Estou analisando aqui e o problema aparenta estar relacionada na verdade com a geração automática das chaves primárias. Nenhuma estratégia de GENERATOR funciona para mais de uma tabela.

Bom dia Pessoal! Continuo na tentativa e ainda não consegui sucesso.

E o erro acontece que vou fazer uma inserção em outra tabela, na primeira tabela que tento inserir funciona, mas ao acessar outra tabela para fazer nova inserção é onde gera o erro.

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: error performing isolated work
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
	at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1152)
	at dao.OrdemServicoDAO.salvar(OrdemServicoDAO.java:26)
	at controller.OrdemServicoController.salvar(OrdemServicoController.java:40)
	at view.OrdemServico.jbtGravarActionPerformed(OrdemServico.java:378)
	at view.OrdemServico.access$300(OrdemServico.java:22)
	at view.OrdemServico$4.actionPerformed(OrdemServico.java:221)
	at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
	at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
	at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
	at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
	at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
	at java.awt.Component.processMouseEvent(Component.java:6533)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
	at java.awt.Component.processEvent(Component.java:6298)
	at java.awt.Container.processEvent(Container.java:2236)
	at java.awt.Component.dispatchEventImpl(Component.java:4889)
	at java.awt.Container.dispatchEventImpl(Container.java:2294)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
	at java.awt.Container.dispatchEventImpl(Container.java:2280)
	at java.awt.Window.dispatchEventImpl(Window.java:2746)
	at java.awt.Component.dispatchEvent(Component.java:4711)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
	at java.awt.EventQueue$4.run(EventQueue.java:731)
	at java.awt.EventQueue$4.run(EventQueue.java:729)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: 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.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId(JpaPersistEventListener.java:67)
	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:189)
	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:132)
	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 org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146)
	... 41 more
Caused by: org.sqlite.SQLiteException: [SQLITE_BUSY]  The database file is locked (database is locked)
	at org.sqlite.core.DB.newSQLException(DB.java:909)
	at org.sqlite.core.DB.newSQLException(DB.java:921)
	at org.sqlite.core.DB.throwex(DB.java:886)
	at org.sqlite.core.DB.exec(DB.java:155)
	at org.sqlite.jdbc3.JDBC3Connection.commit(JDBC3Connection.java:174)
	at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcIsolationDelegate.delegateWork(JdbcIsolationDelegate.java:60)
	... 53 more

Utilizei o padrão singleton, retornando uma EntityManger e após cada operação eu fecho o objeto EntityManager. Já conferi e não há nenhum trecho do código onde tenha esquecido de fechá-lo.

Marcos. Estou tendo o mesmo problema. Já conseguiu resolver?
Skype: alexandregoodmann

Abraços

Alexandre_Goodmann, ainda não. Conversei com outras pessoas me disseram que talvez seja uma limitação da API (no meu caso estava usando JPA) com esse banco de dados. Mas vou confessar que acabei alterando para o Firebird, já conhecia ele e sabia que funcionaria (já tenho outros sistemas utilizando ele).

Concordo que o correto seria testar outras API’s (eclipselink por exemplo) para encontrar o motivo real do problema, mas estava em cima do prazo de entregar o projeto. Era um projeto novo e não havia exigência que fosse determinado banco de dados, por isso optei por utilizar um que já conheço a mais tempo.

Mas se por acaso conseguir resolver, dá um retorno para nós aqui no fórum, essa pode ser a dúvida de outro colega também.

Com SQLite se não me engano tem de usar o @TableGenerator.

GenerationType.AUTO: Valor padrão, deixa com o provedor de persistência a escolha da estratégia mais adequada de acordo com o banco de dados.
GenerationType.IDENTITY: Informamos ao provedor de persistência que os valores a serem atribuídos ao identificador único serão gerados pela coluna de auto incremento do banco de dados. Assim, um valor para o identificador é gerado para cada registro inserido no banco. Alguns bancos de dados podem não suportar essa opção.

Troque:

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int idCliente;

Por:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int idCliente;

E faça um teste.

1 curtida

Olá boa tarde,

Prezados estou também a utilizar o sqlite ou melhor agora ponderando se irei utilizar porque o JPA ( estou usando o Hibernate 5 como provedor ) em um projeto com spring boot não cria a tabela de forma correta, o campo chave que deveria ser criado com autoincremento cria a tabela desta forma
CREATE TABLE Appointment (id integer integer, date timestamp not null, description varchar
not null

Procurei referencias para o uso deste banco com JPA e achei porém não vejo como as informações que ali estão funcionarem uma vez que estou usando a mesma receita e a tabela não é criada de forma correta.

Alguem conseguiu usar sqlite com jpa?