GUJ Discussões   :   últimos tópicos   |   categorias   |   GUJ Respostas

Geração de tabelas automaticamente através da JPA/hibernate.[RESOLVIDO]


#1

Olá Pessoal, não estou conseguindo gerar uma tabela a partir do JPA/hibernate.

Esse é o meu persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence_2_0.xsd">
	<persistence-unit name="pu-meubanco" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<class>modelo.Usuario</class>
		<properties>
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
			<property name="hibernate.hbm2dll.auto" value="update" />
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/meubanco" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="123456" />
		</properties>
	</persistence-unit>
</persistence>

Esse é minha entidade que representa a tabela no banco de dados:

package modelo;
import java.util.Calendar;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
public class Usuario {
	@Id
	@GeneratedValue
	private Long id;
	@Column(unique = true)
	private String email;
	@Temporal(TemporalType.DATE)
	private Calendar dataDeCadastro;
	@Lob
	private byte[] foto;
	//getters e setters
}

E aqui, a minha classe responsável por gerar o banco:

package util;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class GeraTabelas {
	public static void main(String[] args) {
		EntityManagerFactory factory = Persistence
				.createEntityManagerFactory("pu-meubanco");
		factory.close();
	}
}

Já tenho o esquema meubanco criado direitinho. Quando executo o programa nenhuma exception é gerada porém o a tabela também não é gerada.
Vejam o log gerado:

log4j:WARN No such property [conversationPattern] in org.apache.log4j.PatternLayout.
Hibernate Annotations 3.5.0-Final
Hibernate 3.5.0-Final
hibernate.properties not found
Bytecode provider name : javassist
using JDK 1.4 java.sql.Timestamp handling
Hibernate Commons Annotations 3.2.0.Final
Hibernate EntityManager 3.5.0-Final
Binding entity from annotated class: modelo.Usuario
Bind entity modelo.Usuario on table Usuario
Hibernate Validator not found: ignoring
Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate Search is not enabled.
Using Hibernate built-in connection pool (not for production use!)
Hibernate connection pool size: 20
autocommit mode: true
using driver: com.mysql.jdbc.Driver at URL: jdbc:mysql://localhost:3306/meubanco
connection properties: {user=root, password=****, autocommit=true, release_mode=auto}
RDBMS: MySQL, version: 5.1.54-1ubuntu4
JDBC driver: MySQL-AB JDBC Driver, version: mysql-connector-java-5.0.7 ( $Date: 2007-03-09 22:13:57 +0100 (Fri, 09 Mar 2007) $, $Revision: 6341 $ )
Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
Disabling contextual LOB creation as JDBC driver reported JDBC version [3] less than 4
Transaction strategy: org.hibernate.transaction.JDBCTransactionFactory
No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
Automatic flush during beforeCompletion(): disabled
Automatic session close at end of transaction: disabled
JDBC batch size: 15
JDBC batch updates for versioned data: disabled
Scrollable result sets: enabled
JDBC3 getGeneratedKeys(): enabled
Connection release mode: auto
Maximum outer join fetch depth: 2
Default batch fetch size: 1
Generate SQL with comments: disabled
Order SQL updates by primary key: disabled
Order SQL inserts for batching: disabled
Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
Using ASTQueryTranslatorFactory
Query language substitutions: {}
JPA-QL strict compliance: enabled
Second-level cache: enabled
Query cache: disabled
Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory
Optimize cache for minimal puts: disabled
Structured second-level cache entries: disabled
Echoing all SQL to stdout
Statistics: disabled
Deleted entity synthetic identifier rollback: disabled
Default entity-mode: pojo
Named query checking : enabled
Check Nullability in Core (should be disabled when Bean Validation is on): enabled
building session factory
Not binding factory to JNDI, no JNDI name configured
closing
cleaning up connection pool: jdbc:mysql://localhost:3306/meubanco

É óbvio que eu posso construir a tabela na mão, e até fiz isso e criei uma classe de teste para inserir um registro e funcionou perfeitamente. Vejam a classe de teste:

package teste;
import java.util.Calendar;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import modelo.Usuario;
public class AdicionaUsuario {
	public static void main(String[] args) {
		EntityManagerFactory factory = Persistence
				.createEntityManagerFactory("pu-meubanco");
		EntityManager manager = factory.createEntityManager();
		manager.getTransaction().begin();
		Usuario usuario = new Usuario();
		usuario.setEmail("contato@contato.contanto.com..tato");
		usuario.setDataDeCadastro(Calendar.getInstance());
		manager.persist(usuario);
		manager.getTransaction().commit();
		manager.close();
		factory.close();
	}
}

A verdade é que eu fiquei intrigado por não ter conseguido gerar a tabela a partir da classe GeraTabela.java. Alguem poderia me responder porque não estou conseguindo gerar essas tabelas automaticamente pelo JPA/Hibernate?


#2

No arquivo persistence.xml você deve substituir

<property name="hibernate.hbm2dll.auto" value="update" />

por

[code]

Flw....


#3

No arquivo persistence.xml você deve substituir

 <property name="hibernate.hbm2dll.auto" value="update" />

por

 <property name="hibernate.hbm2dll.auto" value="create" />

Flw...


#4

Eu não creio que o problema seja esse, pois o update tb faz create a primeira vez que você roda a aplicação e não existe as tabelas.

Vc criou o database no banco de dados?


#5

Eu usei tanto o valor create, quanto update e create-drop, mas não obtive sucesso. Eu criei o banco normalmente. Como vocês podem ver na classe de teste para inserção, consigo inserir normalmente depois que crio a tabela manualmente. Agradeço a atenção.


#6

Se você está utilizando apenas o JPA você nem precisaria dessa configuração: modelo.Usuario

Dá uma olhada nesse post, ele mostra o passo a passo para que o JPA crie a tabela para você: Hibernate 3 com JPA 2.

Vc pode ter pulado alguma etapa boba.


#7

Tentei sem o modelo.Usuario também, no desepero resolvi colocar. Mas tudo bem vou dar uma olhadinha no link. Obrigado.


#8

Caro JakeFrog,

O Exemplo citado no link também não gera a tabela automaticamente. O exemplo funciona já com a tabela criada no SQL. O que eu estou querendo saber é como fazer para gerar a tabela do banco a partir das configurações do JPA sem precisar escrever SQL para criação do banco. Obrigado.


#9

Eu acho que você entendeu errado.

No exemplo, é criado o database. O JPA não cria o database apenas as tabelas. Repare no post que você não vai ver nenhum comando create table, apenas created database.

O exemplo sim, gera automaticamente a tabela e explica como funciona essa opção:


#10

Eu entendi perfeitamente o exemplo. Criei o database e deixei o resto com a JPA. Veja o que deu:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hibernate: insert into user (name, password) values (?, ?)
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not insert: [com.User]
	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1179)
	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1112)
	at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1118)
	at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:618)
	at com.Main.main(Main.java:20)
Caused by: org.hibernate.exception.SQLGrammarException: could not insert: [com.User]
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2329)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2836)
	at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
	at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:69)
	at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:179)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
	at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:61)
	at org.hibernate.impl.SessionImpl.firePersist(SessionImpl.java:800)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:774)
	at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:778)
	at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:612)
	... 1 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'hello.user' doesn't exist
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
	at com.mysql.jdbc.Util.getInstance(Util.java:384)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1054)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3566)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3498)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2113)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2568)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2113)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2409)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2327)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2312)
	at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
	... 16 more

Ele não gerou a tabela o que ocasionou essa exception aí quando executei a classe Main. Fiz tudo conforme seu tutorial. Vou continuar tentando. Obrigado!


#11

Só não entendi o pq dessa mensagem: "Table 'hello.user' doesn't exist "

Pq hello e . e user? Só não precisa colocar o nome da tabela?

Como que você anotou sua classe depois das alterações?


#12

A classe está anotada exatamente assim:

package com;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "user")
public class User {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	@Column
	private String name;
	@Column
	private String password;
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof User) {
			User user = (User) obj;
			return user.getId() == this.getId();
		}
		return false;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

Uma observação importante é que no tutorial você pede para criar o database hello com o camando

 create database hello;

e lá na propriedade de URL do Banco no persistence.xml você passa

property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/Hello"/>

. Um hello escrito com "h" minusculo e outro "H" maiusculo. Eu deixei o database tudo com "h" minusculo. A unidade de persistencia deixei como estava mesmo: Hello com "H" maiusculo. OK?
Outra observação importante é que se eu crio a tabela user via SQL mesmo então a classe Main executa normalmente fazendo a inserção naturalmente.
Aqui vai o meu persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence_2_0.xsd">
	<persistence-unit name="Hello" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<properties>
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/hello" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="123456" />
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
			<property name="hibernate.hbm2dll.auto" value="update" />
		</properties>
	</persistence-unit>
</persistence>

Por fim a classe Main:

package com;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class Main {
	public static void main(String[] args) {
		EntityManagerFactory emf = Persistence
				.createEntityManagerFactory("Hello");
		EntityManager em = emf.createEntityManager();
		try {
			em.getTransaction().begin();
			User user = em.find(User.class, 1);
			user.setName("123abc");
			em.getTransaction().commit();
		} catch (Exception e) {
			em.getTransaction().rollback();
			e.printStackTrace();
		} finally {
			emf.close();
		}
		System.out.println("It is over");
	}
}

#13

o nome da propriedade do hibernate está escrito errado, no lugar de:

ll.auto" value="update" /> troque por
dl.auto" value="update" />


#14

Realmente o problema estava no nome da propriedade do hibernate que estava escrito errado. Não é dll é ddl (Data Definition Language), dll são as malditas bibliotecas no Ruindows..nada a ver eu ter trocado um pelo o outro..rsrs.. Foi uma desatenção minha. Agradeço a todos que mobilizaram-se para tentar me ajudar em especial o amigo jakeFrog e o Robson_Costa que observou bem onde eu estava errando. Resolvido


#15

[color=darkblue]Na verdade[/color]
JPA

<property name="hibernate.hbm2dll.auto" value="update" />

Hibernate

<property name="hibernate.hbm2ddl.auto" value="update" />

Criação de tabelas no banco automaticamente pelo hibernate
#16

Hebert Coelho

Estava com problemas para gerar tabela no Banco utilizando o Hibernate. Depois que eu li suas dicas retirei
as tags:

<class>modelo.Fabricante</class>

do meu arquivo persistence.xml e funcinou !
Logo depois fiz a inserção na tabela com e sem a as tags class. Por que quando utilizamos o JPA, não precisamos dessa
configuração ? Existe algum momento que ele é indispensavel fiquei muito curioso kkkkkkk

Obrigado!


#17

É como o JPA funciona.

JSE tem implementação que pede essa tag, tem outras que não e assim segue a vida.

Até mais. \o_


#18