Olhei um pouco na net sobre isso, inclusive claro aqui no forum, mais n satisfeito com “quebra galho”, estou postando minha soluçao!
Consideraçoes:
- Estou usando Firebird em modo SuperServer versao 2.0.3 (winXP).
- JDK 6.0 update 3.
- Hibernate Annotations.
CLASSE HIBERNATE_ UTIL:
public class HibernateUtil extends java.lang.Object
{
private static SessionFactory sessionFactory;
//Pegando as informaçoes das propriedades de conexao com a base de dados do software...
private static String usuario = SdpConexao.sdpProps.getProperties().getProperty("db.usuario");
private static String senha = SdpConexao.sdpProps.getProperties().getProperty("db.senha");
private static String dbUrl = SdpConexao.sdpProps.getProperties().getProperty("db.url");
//Criando uma threadLocal garantindo que seja reutilizada a sessao aberta, caso ja exista;
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
static
{
try
{
System.out.println("USER db: " + usuario + " \n senha: " + senha
+ "\n URL: " + dbUrl);
sessionFactory = new AnnotationConfiguration().configure("sdp2000/hibernate.cfg.xml")
.setProperty("hibernate.connection.username", usuario)
.setProperty("hibernate.connection.password", senha)
.setProperty("hibernate.connection.url", dbUrl)
.buildSessionFactory();
}
catch (Exception e)
{
sessionFactory = null;
e.printStackTrace();
System.exit(0);
}
}
public static Session getSession()
{
Session localSession = threadLocal.get();
localSession = sessionFactory.openSession();
threadLocal.set(localSession);
return localSession;
}
public static void initConfMaps()
{
try
{
Session localSession = threadLocal.get();
localSession = sessionFactory.openSession();
threadLocal.set(localSession);
localSession.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
=============================================================================
Sabemos que no Firebird para criar um campo AUTOINCREMENT é preciso criar um GENERATOR para o ID (que é pra ser automatico o incremento)
e uma trigger para executá-lo toda vez que algo for inserido no DB.
No caso de usar o Hibernate, não é preciso criar a trigger, pq ele vai fazer essa computação de incrementar o GENERATOR.
Agora a parte do código em questao (a do auto increment) na minha classe mapeada:
@Entity
@Table(name="CLIENTE")
public class Cliente implements Serializable
{
private static final long serialVersionUID = 1L;
@Id @SequenceGenerator(name = "GEN_ID_CLIENTE", sequenceName = "GEN_CLIENTE_ID")
@GeneratedValue(strategy = GenerationType.AUTO, generator="GEN_ID_CLIENTE")
private Integer id_cliente;
.
.
.
metodos Gets e Sets e bla bla bla.....
}
E agora, por fim a classe ClienteDAO, que é minha interface de controle entre Obj Cliente e tabela Cliente do DB.
Ainda em construçao a classe, mais o que interessa ja está pronto. Que é o rollback do generator caso aconteça um erro ao Salvar um novo registro no DB. Foi necessario a criaçao desse rollBackID porque, quando na tentativa de salvar um novo obj no DB, a primeira coisa a ser calculado é o campo de “auto increment”, a segunda é realiar a persistencia. Se ocorrer erro na persistencia, ele n volta o GENERATPOR (rollBack do calculo do Generator para o proximo valor). Isso causa furos no sequenciamento do ID.
Caso aconteça algum Excepiton no método salve() no seu código, utilize o método rollBak() que está na classe abaixo .
/*
* ClietenDAO.java
*
* Criada em 06 de Desembro de 2007, 14:49
*
* Interface de Controle de Acesso a DADOS do tipo Cliente
*
*/
package sdp2000.persistencia;
import java.util.List;
import org.hibernate.*;
import modCadastro.Cliente;
import org.hibernate.criterion.Example;
/**
*
* @author Rogerio M.Q
*/
public class ClienteDAO
{
private static Session sessao;
/** Creates a new instance of GenericDAO */
public void save( Cliente cliente ) throws Exception
{
sessao = HibernateUtil.getSession();
sessao.beginTransaction();
sessao.save(cliente);
sessao.flush();
sessao.getTransaction().commit();
sessao.close();
}
public void update( Cliente cliente ) throws Exception
{
sessao = HibernateUtil.getSession();
sessao.beginTransaction();
sessao.update(cliente);
sessao.flush();
sessao.getTransaction().commit();
sessao.close();
}
public void salveOrUpdate( Cliente cliente ) throws Exception
{
sessao = HibernateUtil.getSession();
sessao.beginTransaction();
sessao.saveOrUpdate(cliente);
sessao.flush();
sessao.clear();
sessao.getTransaction().commit();
sessao.close();
}
public void delete( Cliente cliente ) throws Exception
{
sessao = HibernateUtil.getSession();
sessao.beginTransaction();
sessao.delete(cliente);
sessao.flush();
sessao.getTransaction().commit();
sessao.close();
}
public List listar(Class clazz) throws Exception
{
sessao = HibernateUtil.getSession();
sessao.beginTransaction();
Cliente exemplo = new Cliente();
exemplo.setStatus_cliente('T');
List clientes;
clientes = null;
Criteria selectAll_T = sessao.createCriteria(clazz).add(Example.create(exemplo)); //revisar
sessao.getTransaction().commit();
clientes = selectAll_T.list();
sessao.close();
return clientes;
}
// Recupera um Registro do Banco, salva em um clienteeto e o retorna para funcao q o chamou.
public Cliente listar(String pk) throws Exception
{
sessao = HibernateUtil.getSession();
sessao.beginTransaction();
Cliente cliente = null;
cliente = (Cliente) sessao.get(Cliente.class, new Integer(Integer.parseInt(pk)) );
sessao.getTransaction().commit();
sessao.flush();
sessao.close();
return cliente;
}
/* Apesar de voltar a ação mal sucedida da SLQ criada pelo hibernate,
no caso uma inserção, o GENERATOR_ID ja foi calculado no FirebirdSQL e assim fujindo da ordem,
entao restartamos o GENERATOR_ID o ultimo maior Id inserido...
*
*
* rollBack customizado para tabela Cliente.
*/
public void rollBack() throws Exception
{
if(sessao.getTransaction()!=null)
{
sessao.getTransaction().rollback();
String rollbackID = "SET GENERATOR GEN_CLIENTE_ID TO " + (getMaxID());
sessao.createSQLQuery(rollbackID).executeUpdate();
}
sessao.close();
}
private int getMaxID()
{
Object obj = sessao.createSQLQuery("SELECT MAX(ID_CLIENTE) AS ID_CLIENTE FROM CLIENTE").uniqueResult();
return Integer.parseInt( obj.toString() );
}
}
qualquer dúvida, estamos ai!