Duvidas Hibernate

20 respostas
R

Caros,

duas perguntinhas de um iniciante em Hibernate:

  1. Onde coloco meus arquivos *.hbm.xml?

2)Estou testando no Acess…no arquivo hobernate.cfg.xml,qual o valor da tag?

abraços

20 Respostas

Thiago_Senna

Qualquer lugar desde que esteja dentro da sua hieráquia de pacotes do projeto, mas o legal mesmo é colocar junto com suas classes ao qual o *.hbm.xml está mapeando.

Hibernate só da suporte para Sistemas Gerenciadores de Banco de Dados. :mrgreen:

hihi, brincadeira… mas o que eu falei em cima é sério. Não sei se hibernate suporta access. Mas eu acho que não deveria suportar mesmo!

Abraços!
Thiago

Mauricio_Linhares

Não, o Hibernate não suporta Access.

Fabricio_Cozer_Marti

Suporta quais entao?

Mauricio_Linhares

Esses: SQL Dialects

Wanderley2k

Opa! Opa! :smiley:

Hibernate suporta MS Access ( Microsoft Acess ) sim. Eu estou usando em uma migração de projeto da minha empresa.

Para que de o suporte primeiro você tem que escrever uma classe de dialect:

package br.com.centauro.dao;

import java.sql.Types;

import org.hibernate.cfg.Environment;
import org.hibernate.dialect.Dialect;

public class MSAccessDialect extends Dialect {
	public MSAccessDialect() {
		super();
		registerColumnType(Types.BIT, "BIT");
		registerColumnType(Types.BIGINT, "INTEGER");
		registerColumnType(Types.SMALLINT, "SMALLINT");
		registerColumnType(Types.TINYINT, "BYTE");
		registerColumnType(Types.INTEGER, "INTEGER");
		registerColumnType(Types.CHAR, "VARCHAR(1)");
		registerColumnType(Types.VARCHAR, "VARCHAR($l)");
		registerColumnType(Types.FLOAT, "DOUBLE");
		registerColumnType(Types.DOUBLE, "DOUBLE");
		registerColumnType(Types.DATE, "DATETIME");
		registerColumnType(Types.TIME, "DATETIME");
		registerColumnType(Types.TIMESTAMP, "DATETIME");
		registerColumnType(Types.VARBINARY, "VARBINARY($l)");
		registerColumnType(Types.NUMERIC, "NUMERIC");

		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE,
				"0");
	}

	public String getIdentityColumnString() {
		return "AutoNumber NOT NULL";
	}

	public String getIdentitySelectString() {
		return "select @@IDENTITY";
	}

}

Depois você tem que colocar ela no hibernate.properties

## Access
hibernate.dialect br.com.centauro.dao.MSAccessDialect
hibernate.connection.driver_class sun.jdbc.odbc.JdbcOdbcDriver
hibernate.connection.url jdbc:odbc:empresario
hibernate.connection.username centauro
hibernate.connection.password centauro

O restante é coisa do Hibernate. Para deixar este post mais completo :smiley: Quando eu comecei a mexer notei que o Access pode setar um atributo de como Permitir Comprimento Zero = Não.

Quando você tenta gravar uma String com tamanho zero dá uma exception. Para resolver este problema meu camarada Thadeu escreveu uma classe que seta todos os campos String de uma classe que tiver .length()=0 para null.

package br.com.centauro.utilitario;

import java.lang.reflect.Method;

/**
 * SetNull.java 13/07/2005
 * 
 * @author Thadeu de Russo e Carmo
 * @author Wanderley Guimarães
 * 
 * (2005) Centauro Portões
 */

public class SetNull {
	public static void setAll(Object obj) {
		try {
			Class clazz = obj.getClass();
			Method[] methods = clazz.getMethods();

			for (int i = 0; i < methods.length; i++) {
				if (methods[i].getReturnType().isAssignableFrom(String.class)) {
					String val = (String) methods[i].invoke(obj,
							(Object[]) null);

					if (val != null && val.length() == 0) {
						String nomeSetMetodo = methods[i].getName()
								.replaceFirst("get", "set");
						Method setMethod = clazz.getMethod(nomeSetMetodo,
								new Class[] { String.class });
						setMethod.invoke(obj, new Object[] { null });
					}
				}
			}
		} catch (Exception e) {
			// TODO colocar isso no log4j
		}
	}
}

Assim você precisa adicionar uma anotação na classe para que seja ignorado os campos null.

@Entity
@org.hibernate.annotations.Entity(dynamicInsert = true, dynamicUpdate = true)
public class Bfj implements Serializable {

Para saber o que são estas anotações:
http://www.hibernate.org/hib_docs/annotations/reference/en/html/entity.html#entity-hibspec-entity
http://www.hibernate.org/hib_docs/v3/reference/en/html/mapping.html#mapping-declaration-class

Acho que é isto. Se eu estiver fazendo algo errado ou que podia ser melhora espero a colaboração da galera.

Até mais,

Mauricio_Linhares

Cara, é vivendo e aprendendo :mrgreen:

Nunca pensei que alguém ia escrever um Dialect pra access. Os relacionamentos funcionam normalmente?

Wanderley2k

Funciona normal. Acontece algumas exception do monitoramento que o hibernate faz no banco de dados. Mas nada que influencie a aplicação.

pcalcado

Pergunta: Ja tentou enviar este dialect como patch pro time do Hibernate? :wink:

Wanderley2k

Na verdade este é baseado no GenericDialect, ele alterar pouca coisa. Acontece que para o meu uso atual não deu nenhum pau. Mas acho que deve precisar de mais coisas para virar um Dialect distribuivel, por enquanto tá como quebra galho. :slight_smile:

Quanto tiver mais tempo vou debulhar alguns Dialect e tentar melhorar ele.

passos

Muito maneiro. Manda pra la!!! :mrgreen:

thadeurc

O legal eh q vc pode fazer um dialeto para qualquer banco de dados (os caras mandaram muito bem na estrutura do projeto).

No fórum do hibernate tem umas coisas legais sobre este assunto e no projeto do wanderley2k tem umas coisas mais “escabrosas” como por exemplo usar do auto-incremento do access.

Mas que se diga de passagem da para fazer “miséria” com o hibernate :slight_smile:

Wanderley2k

Tirando que estou tendo que trabalhar com dois banco de dados diferentes. :smiley: Melhor dois arquivos de dados Access. :slight_smile:

A

segundo a página do hibernate “Community Supported Databases”
http://www.hibernate.org/80.html

o access é suportado sim, através do “HXTT Hibernate Support Package”
http://www.hxtt.com/hibernate.html

ainda não testei, então num sei o qto funciona… mas se tratando de access tá bom demais, hein??

brunalaraujo

Olá!

Eu estou precisando usar o hibernate com access, encontrei esse topico e tentei implementar.
O hibernate ta reconhecendo o banco, mapeando as tabelas, mas na hora do insert dá erro.
Antes do insert o hibernate da uma select max na tabela, funciona de boa, traz o valor do proximo id, mas não consegue inserir.
eu estou utilizando o save.

sessao.save(usuarioVO);

e dá o seguinte erro:?

Hibernate: select max(codUsuario) from usuario
Código retornado pelo select max: 7
Hibernate: /* insert negocio.usuario.UsuarioVO */ insert into usuario (email, senha, codUsuario) values (?, ?, ?)
2008-05-09 09:49:27,187 - 11609 WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: -3500, SQLState: 37000
2008-05-09 09:49:27,187 - 11609 ERROR org.hibernate.util.JDBCExceptionReporter - [Microsoft][Driver ODBC para Microsoft Access] Instrução SQL inválida. ‘DELETE’, ‘INSERT’, ‘PROCEDURE’, ‘SELECT’ ou ‘UPDATE’ esperado.
2008-05-09 09:49:27,187 - 11609 ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.SQLGrammarException: could not insert: [negocio.usuario.UsuarioVO]

Metallica

Nossa muito interessante.
Eu uso aqui a seguinte URL pro Access: jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};dbq=C/banco.mdb
Já tentei por isso no properties

hibernate.connection.url jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};dbq=C/banco.mdb

Mas tá me dando uma NullPointerException a hora que eu tento dar um session.save(obj);

Como faço quando quero acessar um .mdb específico?

R

ae bruna, sera que vc conseguiu inserir usando o access ? cai no mesmo problema seu … caso conseguir me posta ai …

phfaustino

Não sei se vai te ajudar, mas ta aí um post interessante sobre Hibernate + Access !

http://www.guj.com.br/posts/list/27514.java

AlencarCanton

e ae galera,beleza?
to precisando acessar um banco de dados access através do hibernate,
implementei o dialect que o nosso amigo aí postou,mudei o hibernate.cfg.xml,mas quando tento salvar um objeto no banco tá gerando uma exceção,parece que ele n tá achando o driver,ou tá com algum problema nessa parte,segue meu xml:

<hibernate-configuration> <session-factory> <property name="hibernate.connection.username"></property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.url">jdbc:odbc:MaoDeObra1</property> <property name="hibernate.connection.driver_class">sun.jdbc.odbc.JdbcOdbcDriver</property> <property name="hibernate.dialect">br.com.centauro.dao.MSAccessDialect</property> <property name="hibernate.hbm22ddl.auto">update</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping class="opcontroller.Beans.Funcionario" /> <!-- As classes relacionais devem ser mapeadas // Este arquivo deve estar no pacote padrão--> <mapping class="opcontroller.Beans.FilhoFuncionario" /> <mapping class="opcontroller.Beans.CursoFuncionario" /> <mapping class="opcontroller.Beans.Ocorrencia" /> </session-factory> </hibernate-configuration>

segue a exceção gerada pelo IDE:

Exception in thread "main" org.hibernate.exception.GenericJDBCException: Cannot open connection at org.hibernate.exception.SQLStateConverter.handledNonSpecificException(SQLStateConverter.java:140) at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:128) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:52) at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:449) at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:167) at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:160) at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:81) at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1473) at opcontroller.DAO.FuncionarioDAO.insere(FuncionarioDAO.java:27) at opcontroller.Main.main(Main.java:49) Caused by: java.sql.SQLException: [Microsoft][ODBC Driver Manager] Nome da fonte de dados n?o encontrado e nenhum driver padr?o especificado at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6956) at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7113) at sun.jdbc.odbc.JdbcOdbc.SQLDriverConnect(JdbcOdbc.java:3072) at sun.jdbc.odbc.JdbcOdbcConnection.initialize(JdbcOdbcConnection.java:323) at sun.jdbc.odbc.JdbcOdbcDriver.connect(JdbcOdbcDriver.java:174) at java.sql.DriverManager.getConnection(DriverManager.java:579) at java.sql.DriverManager.getConnection(DriverManager.java:190) at org.hibernate.connection.DriverManagerConnectionProvider.getConnection(DriverManagerConnectionProvider.java:133) at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:446) ... 6 more Java Result: 1

alguém pode dar uma olhada no meu xml?não sei como posso arrumar isso…

@brunalaraujo
Voce disse q o hibernate tá encontrado o banco e reconhecendo as tabelas,será q vc pode postar aqui o seu xml de configuração pra eu dar uma olhada?vlw!

vlw pela atenção,galera!abraço!

AlencarCanton

Galera,

Sei que esse tópico é antigo mas eu consegui fazer funcionar e acho que vai acrescentar conhecimento caso alguem um dia precise disso.

Segue o xml de cfg do hibernate que eu usei para acessar um banco de MS Access:

<hibernate-configuration> <session-factory> <property name="hibernate.connection.username"></property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.url">jdbc:access:///D:\users\fa039420\Documents\NetBeansProjects\OpController\src\MaoDeObra1.accdb</property> <property name="hibernate.connection.driver_class">com.hxtt.sql.access.AccessDriver</property> <property name="hibernate.dialect">br.com.centauro.dao.MSAccessDialect</property> <property name="hibernate.hbm22ddl.auto">update</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <mapping class="opcontroller.Beans.Funcionario" /> <!-- As classes relacionais devem ser mapeadas // Este arquivo deve estar no pacote padrão--> <mapping class="opcontroller.Beans.FilhoFuncionario" /> <mapping class="opcontroller.Beans.CursoFuncionario" /> <mapping class="opcontroller.Beans.Ocorrencia" /> </session-factory> </hibernate-configuration>

Utilizei o Dialect implementado por um amigo aqui do fórum,o código dele tá nesse tópico mesmo.O driver que eu usei foi o com.hxtt.sql.access.AccessDriver,precisei baixar e colocar no classpath: o “Access_Core_JDBC41.jar” e o “Access_JDBC41.jar” que eu consegui no www.hxtt.com
só isso :smiley: vlw galera!

Spool

Cara muito bom esse post.
Vou tentar a implementação e depois posto o resultado.

Agradeço por compartilhar!

Criado 13 de julho de 2005
Ultima resposta 18 de jan. de 2008
Respostas 20
Participantes 15