Camaradas,
Estou desenvolvendo uma aplicação para testar o Hibernate 4. Até então, estava muito bem obrigado com o Hibernate 3.6.10, porém, por uma questão de conhecimento, resolvi ver como está a nova versão. Já havia feito alguns testes antes, todos me trouxeram problemas.
Utilizo anotações e faço os testes como aplicação local, embora seja web.
Primeiramente comecei utilizando a estrutura básica de jars, que estão na versão a ser baixada no sourceforge.Aqui.
Tive problemas com o NoClassDefFound para as classes dos jars jandex-1.0.3.Final e classmate-0.5.4.
Após inserir os mesmos no buildpath, qual a minha surpresa, com esta mensagem de erro:
Could not instantiate persister org.hibernate.persister.entity.SingleTableEntityPersister
E o stack é:
22/08/2012 11:30:29 org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.1.6.Final}
22/08/2012 11:30:29 org.hibernate.cfg.Environment <clinit>
INFO: HHH000205: Loaded properties from resource hibernate.properties: {hibernate.connection.username=root, hibernate.connection.password=****, hibernate.dialect=org.hibernate.dialect.MySQLDialect, hibernate.show_sql=true, hibernate.connection.url=jdbc:mysql://localhost:3306/naptec, hibernate.bytecode.use_reflection_optimizer=false, hibernate.connection.driver_class=com.mysql.jdbc.Driver, hibernate.hbm2ddl.auto=update}
22/08/2012 11:30:29 org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
22/08/2012 11:30:30 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000402: Using Hibernate built-in connection pool (not for production use!)
22/08/2012 11:30:30 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20
22/08/2012 11:30:30 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000006: Autocommit mode: false
22/08/2012 11:30:30 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000401: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/naptec]
22/08/2012 11:30:30 org.hibernate.service.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000046: Connection properties: {user=root, password=****}
22/08/2012 11:30:30 org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
22/08/2012 11:30:31 org.hibernate.engine.transaction.internal.TransactionFactoryInitiator initiateService
INFO: HHH000399: Using default transaction strategy (direct JDBC transactions)
22/08/2012 11:30:31 org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory <init>
INFO: HHH000397: Using ASTQueryTranslatorFactory
org.hibernate.MappingException: Could not instantiate persister org.hibernate.persister.entity.SingleTableEntityPersister
at org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:174)
at org.hibernate.persister.internal.PersisterFactoryImpl.createEntityPersister(PersisterFactoryImpl.java:148)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:736)
at org.hibernate.metamodel.source.internal.SessionFactoryBuilderImpl.buildSessionFactory(SessionFactoryBuilderImpl.java:65)
at org.hibernate.metamodel.source.internal.MetadataImpl.buildSessionFactory(MetadataImpl.java:340)
at br.com.naptec.biblioteca.dao.util.HibernateUtil.getSession(HibernateUtil.java:29)
at br.com.naptec.biblioteca.dao.AbstractDAO.criaSession(AbstractDAO.java:21)
at br.com.naptec.biblioteca.dao.AbstractDAO.saveOrUpdate(AbstractDAO.java:39)
at br.com.naptec.biblioteca.dao.LivroDAOImpl.saveOrUpdate(LivroDAOImpl.java:18)
at br.com.naptec.biblioteca.services.LivroService.saveOrUpdate(LivroService.java:20)
at br.com.naptec.biblioteca.teste.Teste.main(Teste.java:22)
Caused by: java.lang.NullPointerException
at org.hibernate.tuple.PropertyFactory.buildStandardProperty(PropertyFactory.java:288)
at org.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:442)
at org.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:793)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:462)
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 org.hibernate.persister.internal.PersisterFactoryImpl.create(PersisterFactoryImpl.java:163)
... 10 more
java.lang.NullPointerException
at br.com.naptec.biblioteca.dao.AbstractDAO.criaSession(AbstractDAO.java:22)
at br.com.naptec.biblioteca.dao.AbstractDAO.saveOrUpdate(AbstractDAO.java:39)
at br.com.naptec.biblioteca.dao.LivroDAOImpl.saveOrUpdate(LivroDAOImpl.java:18)
at br.com.naptec.biblioteca.services.LivroService.saveOrUpdate(LivroService.java:20)
at br.com.naptec.biblioteca.teste.Teste.main(Teste.java:22)
A princípio, pensei que fosse problema com os mapeamentos (vi no jira do hibernate e no stackoverflow que se algum método getter estivesse sem anotação, poderia ocorrer), porém, nada.
Depois, ataquei os OneToMany e ManyToOne (eu havia criado duas entidades, Livro e Autor e uma entidade que relacionava ambos, LivroAutor). Porém, sem sucesso.
Após isto, mapeei diretamente livros e autores, criando um ManyToMany.
Sem sucesso.
Portanto, venho até aqui para ver se consigo alguma ajuda.
Os jars que estou utilizando são:
antlr-2.7.7.jar
classmate-0.5.4.jar
dom4j-1.6.6.1.jar
hibernate-commons-annotations-4.0.1.Final.jar
hibernate-core-4.1.6.Final.jar
hibernate-entitymanager-4.1.6.Final.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
jandex-2.0.3.Final.jar
javassist-3.15.0.GA.jar
jboss-logging-3.1.0.GA.jar
jboss-transaction-api_1.1_spec-1.0.0.Final.jar
mysql-connector-java-5.1.21-bin.jar
javax.faces-2.1.12.jar
Banco de dados MySQL 5.1
Realizando o debug, identifiquei que o problema ocorre no método construtor da classe SessionFactoryImpl, quando o Hibernate tenta obter o Service a partir da entity mapeada.
O trecho do método é este (reparem no TODO grandão ali):
entityPersisters = new HashMap<String,EntityPersister>();
Map<String, RegionAccessStrategy> entityAccessStrategies = new HashMap<String, RegionAccessStrategy>();
Map<String,ClassMetadata> classMeta = new HashMap<String,ClassMetadata>();
for ( EntityBinding model : metadata.getEntityBindings() ) {
// TODO: should temp table prep happen when metadata is being built?
//model.prepareTemporaryTables( metadata, getDialect() );
// cache region is defined by the root-class in the hierarchy...
EntityBinding rootEntityBinding = metadata.getRootEntityBinding( model.getEntity().getName() );
EntityRegionAccessStrategy accessStrategy = null;
if ( settings.isSecondLevelCacheEnabled() &&
rootEntityBinding.getHierarchyDetails().getCaching() != null &&
model.getHierarchyDetails().getCaching() != null &&
model.getHierarchyDetails().getCaching().getAccessType() != null ) {
final String cacheRegionName = cacheRegionPrefix + rootEntityBinding.getHierarchyDetails().getCaching().getRegion();
accessStrategy = EntityRegionAccessStrategy.class.cast( entityAccessStrategies.get( cacheRegionName ) );
if ( accessStrategy == null ) {
final AccessType accessType = model.getHierarchyDetails().getCaching().getAccessType();
if ( LOG.isTraceEnabled() ) {
LOG.tracev( "Building cache for entity data [{0}]", model.getEntity().getName() );
}
EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion(
cacheRegionName, properties, CacheDataDescriptionImpl.decode( model )
);
accessStrategy = entityRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
cacheAccess.addCacheRegion( cacheRegionName, entityRegion );
}
}
EntityPersister cp = serviceRegistry.getService( PersisterFactory.class ).createEntityPersister(
model, accessStrategy, this, metadata
);
entityPersisters.put( model.getEntity().getName(), cp );
classMeta.put( model.getEntity().getName(), cp.getClassMetadata() );
}
Se alguém tiver uma luz, ou consegue utilizar o hibernate 4, por gentileza, ficarei grato com a colaboração.