My goal is to generate DDL during build time. I have exec-maven-plugin with goal to execute main method below:
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
SessionFactoryImpl sessionFactory = null;
try {
Persistence.generateSchema(PERSISTENCE_UNIT, null);
} finally {
sessionFactory = emf.unwrap(SessionFactoryImpl.class);
sessionFactory.getServiceRegistry().destroy();
}
}
my persistence.xml
<?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="ddl-gen">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>***</class>
<class>***</class>
<class>***</class>
<properties>
<property name="javax.persistence.schema-generation.scripts.action" value="create"/>
<property name="javax.persistence.schema-generation.scripts.create-target"
value="${project.basedir}/src/main/resources/META-INF/sql/init.sql"/>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://***/~/***"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
</properties>
</persistence-unit>
</persistence>
But the problem is Hibernate wont kill DB connection even if I do it explicitly. Execution does not finishing and the process is endless
Logs:
16:11:41.062 [main] DEBUG org.hibernate.internal.SessionFactoryRegistry - Not binding SessionFactory to JNDI, no JNDI name configured
16:11:41.062 [main] DEBUG org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator - wasInitiallyAutoCommit=false
16:11:41.062 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
16:11:41.066 [main] DEBUG org.hibernate.service.internal.AbstractServiceRegistryImpl - Implicitly destroying ServiceRegistry on de-registration of all child ServiceRegistries
16:11:41.066 [main] INFO org.hibernate.orm.connections - HHH10001008: Cleaning up connection pool [jdbc:h2:tcp://***/~/***]
16:11:41.067 [main] DEBUG org.hibernate.boot.registry.internal.BootstrapServiceRegistryImpl - Implicitly destroying Boot-strap registry on de-registration of all child ServiceRegistries
16:12:10.932 [pool-2-thread-1] DEBUG org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl - Connection pool now considered primed; min-size will be maintained
Intresting thing is that I have [pool-2-thread-1] It means Hibernate creates new pool. because without explisit killing i have this log:
public static void main(String[] args) {
Persistence.generateSchema(PERSISTENCE_UNIT, null);
}
16:07:26.890 [main] DEBUG org.hibernate.internal.SessionFactoryRegistry - Not binding SessionFactory to JNDI, no JNDI name configured
16:07:26.895 [main] DEBUG org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator - wasInitiallyAutoCommit=false
16:07:26.896 [main] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
16:07:54.274 [pool-1-thread-1] DEBUG org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl - Connection pool now considered primed; min-size will be maintained
I've found solution.
The problem with Hibernate is that he can't close connection. (this was not fixed in my solution).
So the idea was not create this connection per generation.
Hibernate provides dummy ConnectionProvider.class
org.hibernate.engine.jdbc.connections.internal.UserSuppliedConnectionProviderImpl
which is not good for this purpose because it throws RuntimeException
see below:
#Override
public Connection getConnection() throws SQLException {
throw new UnsupportedOperationException( "The application must supply JDBC connections" );
}
So my idea was create my custom implementation of ConnectionProvider.classand using persistence.xml and <property name="hibernate.connection.provider_class" value="com.akhambir.ddl.ddl_gen.DLLGeneratorConnectionProvider"/> use it within my persistence-unit.
DLLGeneratorConnectionProvider.class has no implementation inside, just returns not implemented anonymous Connection and Statement from getConnection() which helps avoid creation real connection for HibernatePersistenceProvider.class.
Also find my workable version of the schema-generation at build time on GitHub : https://github.com/akhambir/jpa2.1-schema-generator-with-hibernate
Related
I'm running an Java EE application on Wildfly 15.0.1. I'm trying to use JPA without creating datasource on wildfly, because I want all the dependencies to be packed in application source code. I am using Maven to build the WAR.
I am using PostgreSQL and it's up and running on http://localhost:5432 I create db called testing for this project.
So, I added this dependency to my pom.xml:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
My persistence.xml is in src/main/resources/META-INF/persistence.xml:
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.2"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">
<persistence-unit name="pu1">
<!-- classes -->
<class>myapp.model.Address</class>
<class>myapp.model.Transaction</class>
<properties>
<!-- database connection -->
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/testing" />
<property name="javax.persistence.jdbc.user" value="postgres" />
<property name="javax.persistence.jdbc.password" value="postgres" />
<!-- hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
I have #Entity annotation on both my Address and Transaction classes. But, nothing happens. Here's the log snippet:
22:58:05,759 INFO [org.hibernate.jpa.internal.util.LogHelper] (ServerService Thread Pool -- 103) HHH000204: Processing PersistenceUnitInfo [
name: pu1
...]
22:58:05,760 INFO [org.jboss.weld.deployer] (MSC service thread 1-5) WFLYWELD0003: Processing weld deployment myapp.backend-1.0.war
22:58:05,791 WARN [org.jboss.as.jaxrs] (MSC service thread 1-3) WFLYRS0018: Explicit usage of Jackson annotation in a JAX-RS deployment; the system will disable JSON-B processing for the current deployment. Consider setting the 'resteasy.preferJacksonOverJsonB' property to 'false' to restore JSON-B.
22:58:05,796 INFO [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-3) WFLYJCA0005: Deploying non-JDBC-compliant driver class org.postgresql.Driver (version 42.2)
22:58:05,810 INFO [org.jboss.as.connector.deployers.jdbc] (MSC service thread 1-8) WFLYJCA0018: Started Driver service with driver-name = myapp.backend-1.0.war_org.postgresql.Driver_42_2
22:58:05,816 INFO [org.jboss.as.jpa] (ServerService Thread Pool -- 103) WFLYJPA0010: Starting Persistence Unit (phase 2 of 2) Service 'myapp.backend-1.0.war#pu1'
22:58:05,817 INFO [org.hibernate.dialect.Dialect] (ServerService Thread Pool -- 103) HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL94Dialect
22:58:05,820 INFO [org.hibernate.type.BasicTypeRegistry] (ServerService Thread Pool -- 103) HHH000270: Type registration [java.util.UUID] overrides previous : org.hibernate.type.UUIDBinaryType#6543510a
22:58:05,822 INFO [org.hibernate.envers.boot.internal.EnversServiceImpl] (ServerService Thread Pool -- 103) Envers integration enabled? : true
22:58:05,858 INFO [org.hibernate.tool.schema.internal.SchemaCreatorImpl] (ServerService Thread Pool -- 103) HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl#4cc01a34'
22:58:05,858 INFO [org.hibernate.hql.internal.QueryTranslatorFactoryInitiator] (ServerService Thread Pool -- 103) HHH000397: Using ASTQueryTranslatorFactory
JPA specification:
8.2.1.2 transaction-type
The transaction-type attribute is used to specify whether the entity
managers provided by the entity manager factory for the persistence
unit must be JTA entity managers or resource-local entity managers.
The value of this element is JTA or RESOURCE_LOCAL. A transaction-type
of JTA assumes that a JTA data source will be provided—either as
specified by the jta-data-source element or provided by the container.
In general, in Java EE environments, a transaction-type of
RESOURCE_LOCAL assumes that a non-JTA datasource will be provided. In
a Java EE environment, if this element is not specified, the default
is JTA. In a Java SE environment, if this element is not specified,
the default is RESOURCE_LOCAL.
JTA is default transaction type in EE application server. To use it you need a datasource configured in WildFly. Then add it to persistence.xml:
<persistence-unit name="pu1" transaction-type="JTA">
<!-- classes -->
<class>myapp.model.Address</class>
<class>myapp.model.Transaction</class>
<properties>
<jta-data-source>jdbc/jndi_name_of_datasource</jta-data-source>
<!-- hibernate -->
<property name="hibernate.hbm2ddl.auto" value="create"/>
</properties>
</persistence-unit>
This question has been asked many times, but I have not encountered a solution for my problem as on first sight everything seems right. It is a configuration problem when using this Hibernate setup:
hibernate-core: 5.2.11.Final
hibernate-jpa-2.1-api: 1.0.0.Final
hibernate-commons-annotations: 5.0.1.Final
When I try to execute a query I get a warning in the console that says no persistent classes found for query class but no error is thrown, and no data is retrieved from database although it should return over 30 entries.
09:56:58,203 INFO [org.hibernate.Version] (default task-46) HHH000412: Hibernate Core {5.2.11.Final}
09:56:58,206 INFO [org.hibernate.cfg.Environment] (default task-46) HHH000206: hibernate.properties not found
09:56:58,348 INFO [org.hibernate.annotations.common.Version] (default task-46) HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
09:56:58,397 WARN [org.hibernate.orm.connections.pooling] (default task-46) HHH10001002: Using Hibernate built-in connection pool (not for production use!)
09:56:58,398 INFO [org.hibernate.orm.connections.pooling] (default task-46) HHH10001005: using driver [com.mysql.cj.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/db_motor?useSSL=false&autoReconnect=true]
09:56:58,398 INFO [org.hibernate.orm.connections.pooling] (default task-46) HHH10001001: Connection properties: {user=admin, password=****}
09:56:58,398 INFO [org.hibernate.orm.connections.pooling] (default task-46) HHH10001003: Autocommit mode: false
09:56:58,400 INFO [org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl] (default task-46) HHH000115: Hibernate connection pool size: 10 (min=1)
09:56:58,647 INFO [org.hibernate.dialect.Dialect] (default task-46) HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
09:56:58,958 WARN [org.hibernate.hql.internal.QuerySplitter] (default task-46) HHH000183: no persistent classes found for query class: SELECT respuestas FROM mr.hibernate.beans.MR_RespuestasHBean respuestas
09:56:58,959 INFO [org.hibernate.hql.internal.QueryTranslatorFactoryInitiator] (default task-46) HHH000397: Using ASTQueryTranslatorFactory
It seems the warning about hibernate.properties not found is not of any influence if I interpret information found on this website correctly.
The hibernate.cfg.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="session_factory">
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.password">admin</property>
<property name="connection.pool_size">10</property> <!-- not for production -->
<property name="connection.url">jdbc:mysql://localhost:3306/db_motor?useSSL=false&autoReconnect=true</property>
<property name="connection.username">admin</property>
<property name="hibernate.bytecode.use_reflection_optimizer">false</property>
<property name="hibernate.current_session_context_class">thread</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
<mapping class="mr.hibernate.beans.MR_RespuestasHBean"/>
</session-factory>
</hibernate-configuration>
The mapped class:
package mr.hibernate.beans;
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.Table;
#Entity
#Table(name = "t_respuestas")
public class MR_RespuestasHBean implements Serializable {
private static final long serialVersionUID = 3892055031093758454L;
#Id
#Column(name = "COD_RESPUESTA", nullable = false, length = 11)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long codigoRespuesta;
public Long getCodigoRespuesta() {
return codigoRespuesta;
}
public void setCodigoRespuesta(Long codigoRespuesta) {
this.codigoRespuesta = codigoRespuesta;
}
}
Table definition:
CREATE TABLE t_respuestas
(
COD_RESPUESTA int PRIMARY KEY NOT NULL
)
;
CREATE UNIQUE INDEX PRIMARY ON t_respuestas(COD_RESPUESTA)
;
The code used to get the query is this:
session = getSession(HibernateUtil.configurationFileMySql);
session.beginTransaction();
StringBuffer hql = new StringBuffer();
StringBuffer select = new StringBuffer();
select.append("SELECT respuestas");
StringBuffer from = new StringBuffer();
from.append(" FROM "+ MR_RespuestasHBean.class.getName() +" respuestas");
hql.append(select);
hql.append(from);
#SuppressWarnings("unchecked")
Query<MR_RespuestasHBean> query = session.createQuery(hql.toString());
listado = query.list();
If I change MR_RespuestasHBean.class.getName() by MR_RespuestasHBean.class.getSimpleName(), an error is thrown:
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: MR_RespuestasHBean is not mapped
Some information on the environment:
JBoss EAP7
JDK8
MySql connector 6.0.6
The Hibernate part is in an EJB3 project
However, when using this setup, everything works well (logically, session loading and query execution has to be different):
hibernate-core: 4.2.0.Final
hibernate-jpa-2.0-api: 1.0.1.Final
hibernate-commons-annotations: 4.0.1.Final
Any clues on what is causing the problem is very much appreciated.
I'm working on a project with EJB, Hibernate and JBoss, I got a problem on JBoss startup. JBoss found my datasource but stops here:
15:42:14,035 INFO [EntityBinder] Bind entity br.com.sankhya.teste.model.entities.ContatoCliente on table CONTATO_CLIENTE 15:42:14,201 INFO [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider 15:42:14,209 INFO [InjectedDataSourceConnectionProvider] Using provided datasource
I put timeout to 1000 seconds and even with this JBoss doesn't start. This is the full log and my code:
15:42:13,277 INFO [A] Bound to JNDI name: queue/A
15:42:13,278 INFO [B] Bound to JNDI name: queue/B
15:42:13,279 INFO [C] Bound to JNDI name: queue/C
15:42:13,279 INFO [D] Bound to JNDI name: queue/D
15:42:13,280 INFO [ex] Bound to JNDI name: queue/ex
15:42:13,293 INFO [testTopic] Bound to JNDI name: topic/testTopic
15:42:13,294 INFO [securedTopic] Bound to JNDI name: topic/securedTopic
15:42:13,295 INFO [testDurableTopic] Bound to JNDI name: topic/testDurableTopic
15:42:13,297 INFO [testQueue] Bound to JNDI name: queue/testQueue
15:42:13,328 INFO [UILServerILService] JBossMQ UIL service available at : /127.0.0.1:8093
15:42:13,354 INFO [DLQ] Bound to JNDI name: queue/DLQ
15:42:13,432 INFO [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=JmsXA' to JNDI name 'java:JmsXA'
15:42:13,467 INFO [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=DataSourceBinding,name=TesteDS' to JNDI name 'java:TesteDS'
15:42:13,667 INFO [JmxKernelAbstraction] creating wrapper delegate for: org.jboss.ejb3.entity.PersistenceUnitDeployment
15:42:13,671 INFO [JmxKernelAbstraction] installing MBean: persistence.units:jar=ClientesModel.jar,unitName=clientes with dependencies:
15:42:13,671 INFO [JmxKernelAbstraction] jboss.jca:name=TesteDS,service=DataSourceBinding
15:42:13,672 INFO [PersistenceUnitDeployment] Starting persistence unit persistence.units:jar=ClientesModel.jar,unitName=clientes
15:42:13,695 INFO [Version] Hibernate EntityManager 3.2.1.GA
15:42:13,712 INFO [Version] Hibernate Annotations 3.2.1.GA
15:42:13,720 INFO [Environment] Hibernate 3.2.4.sp1
15:42:13,725 INFO [Environment] hibernate.properties not found
15:42:13,726 INFO [Environment] Bytecode provider name : javassist
15:42:13,731 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling
15:42:13,855 INFO [Ejb3Configuration] found EJB3 Entity bean: br.com.sankhya.teste.model.entities.Cliente
15:42:13,855 INFO [Ejb3Configuration] found EJB3 Entity bean: br.com.sankhya.teste.model.entities.ContatoCliente
15:42:13,855 INFO [Ejb3Configuration] found EJB3 #Embeddable: br.com.sankhya.teste.model.entities.ContatoClientePK
15:42:13,877 INFO [Configuration] Reading mappings from resource : META-INF/orm.xml
15:42:13,879 INFO [Ejb3Configuration] [PersistenceUnit: clientes] no META-INF/orm.xml found
15:42:13,934 INFO [AnnotationBinder] Binding entity from annotated class: br.com.sankhya.teste.model.entities.Cliente
15:42:13,988 INFO [EntityBinder] Bind entity br.com.sankhya.teste.model.entities.Cliente on table Cliente
15:42:14,035 INFO [AnnotationBinder] Binding entity from annotated class: br.com.sankhya.teste.model.entities.ContatoCliente
15:42:14,035 INFO [EntityBinder] Bind entity br.com.sankhya.teste.model.entities.ContatoCliente on table CONTATO_CLIENTE
15:42:14,201 INFO [ConnectionProviderFactory] Initializing connection provider: org.hibernate.ejb.connection.InjectedDataSourceConnectionProvider
15:42:14,209 INFO [InjectedDataSourceConnectionProvider] Using provided datasource
persistence unit
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.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/persistence_1_0.xsd">
<persistence-unit name="clientes" transaction-type="JTA">
<jta-data-source>java:TesteDS</jta-data-source>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
</properties>
</persistence-unit>
</persistence>
datasource
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local-tx-datasource>
<jndi-name>TesteDS</jndi-name>
<connection-url>jdbc:mysql://localhost:8080/prog_test_db</connection-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<user-name>root</user-name>
<password>sissis</password>
<min-pool-size>5</min-pool-size>
<max-pool-size>20</max-pool-size>
<idle-timeout-minutes>5</idle-timeout-minutes>
<exception-sorter-class-name>com.mysql.jdbc.integration.jboss.ExtendedMysqlExceptionSorter</exception-sorter-class-name>
<valid-connection-checker-class-name>com.mysql.jdbc.integration.jboss.MysqlValidConnectionChecker</valid-connection-checker-class-name>
<transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
</local-tx-datasource>
</datasources>
Could you help me ? thanks
Environment:
Java/Spring application that uses JPA/Hibernate for persistence and connects to a Teradata datasource configured in the app container (Tomcat) which is accessed through JNDI.
Versions that I am using:
java: 6
spring: 3.2.4.RELEASE
hibernate.core: 4.2.4.Final
hibernate.entitymanager: 4.2.4.Final
hibernate.validator: 5.0.1.Final
springdata: 1.3.4.RELEASE
javax.validation: 1.1.0.Final
Problem:
There are two Teradata databases in the same server that have a same named table but with different columns:
DatDe001.SFITEM
Columns: [iipcst, iidesc, iivend, updated_at, iisku#, created_at, item_expdt, item_effdt]
DEV_DIG_UMT.SFITEM
Columns: [iipcst, iidesc, iivend, row_updt_tms, iisku#, row_insrt_tms, item_expdt, item_effdt]
As you can see the columns that differ are updated_at -> row_updt_tms and created_at -> row_insrt_tms
I am using a JNDI datasource which is configured using this jdbc url:
jdbc:teradata://<server_ip>/DATABASE=DEV_DIG_UMT,DBS_PORT=1025,COP=OFF,CHARSET=UTF8,TMODE=ANSI
It is supposed that the jdbc connection will resolve the location of the table using the DATABASE value in that jdbc url. However Hibernate seems to be taking the wrong one: DatDe001.SFITEM when performing the initial schema validation, that is at the moment of context initialization when Spring tries to create the EntityManagerFactory bean:
2013-08-15 13:32:03,635 INFO localhost-startStop-1 org.hibernate.tool.hbm2ddl.TableMetadata - HHH000261: Table found: DatDe001.SFITEM
2013-08-15 13:32:03,635 INFO localhost-startStop-1 org.hibernate.tool.hbm2ddl.TableMetadata - HHH000037: Columns: [iipcst, iidesc, iivend, updated_at, iisku#, created_at, item_expdt, item_effdt]
So as my JPA entity (see the entity below in the post) does not have those columns, the hibernate validation throws an exception (see the summarized stack trace):
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in file [C:\APP\springsource\vfabric-tc-server-developer-2.9.2.RELEASE\base-instance\wtpwebapps\profile-items\WEB-INF\classes\META-INF\spring\applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in file [C:\APP\springsource\vfabric-tc-server-developer-2.9.2.RELEASE\base-instance\wtpwebapps\profile-items\WEB-INF\classes\META-INF\spring\applicationContext.xml]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1482)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:521)
...
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: persistenceUnit] Unable to build EntityManagerFactory
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:924)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:899)
...
Caused by: org.hibernate.HibernateException: Missing column: row_updt_tms in DatDe001.SFITEM
at org.hibernate.mapping.Table.validateColumns(Table.java:366)
at org.hibernate.cfg.Configuration.validateSchema(Configuration.java:1305)
at org.hibernate.tool.hbm2ddl.SchemaValidator.validate(SchemaValidator.java:155)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:508)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1790)
at org.hibernate.ejb.EntityManagerFactoryImpl.<init>(EntityManagerFactoryImpl.java:96)
at org.hibernate.ejb.Ejb3Configuration.buildEntityManagerFactory(Ejb3Configuration.java:914)
After I saw that, I was wondering if this behavior will persist when executing a query statement to the db through JPA/hibernate, or if it will point to the right table in that case.
Then just for investigation purposes I changed my JPA entity to have the same columns that DatDe001.SFITEM table:
#Entity
public class Sfitem implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SfitemPK id;
#Column(name="\"iidesc\"")
private String iidesc;
#Column(name="\"iipcst\"")
private BigDecimal iipcst;
#Column(name="\"iivend\"")
private BigDecimal iivend;
#Temporal
#Column(name="\"item_expdt\"")
private Date itemExpdt;
#Temporal
#Column(name="\"created_at\"")
private Date createdAt;
#Temporal
#Column(name="\"updated_at\"")
private Date updatedAt;
...
}
I started the application and it got loaded successfully. Instead of showing the exception now the log looked good:
...
2013-08-15 14:42:52,056 INFO localhost-startStop-1 org.hibernate.tool.hbm2ddl.TableMetadata - HHH000261: Table found: DatDe001.SFITEM
2013-08-15 14:42:52,056 INFO localhost-startStop-1 org.hibernate.tool.hbm2ddl.TableMetadata - HHH000037: Columns: [iipcst, iidesc, iivend, updated_at, iisku#, created_at, item_expdt, item_effdt]
2013-08-15 14:42:52,061 DEBUG localhost-startStop-1 org.hibernate.internal.SessionFactoryImpl - Checking 0 named HQL queries
2013-08-15 14:42:52,061 DEBUG localhost-startStop-1 org.hibernate.internal.SessionFactoryImpl - Checking 0 named SQL queries
2013-08-15 14:42:52,063 TRACE localhost-startStop-1 org.hibernate.service.internal.AbstractServiceRegistryImpl - Initializing service [role=org.hibernate.service.config.spi.ConfigurationService]
2013-08-15 14:42:52,113 TRACE localhost-startStop-1 org.hibernate.service.internal.AbstractServiceRegistryImpl - Initializing service [role=org.hibernate.stat.spi.StatisticsImplementor]
...
I tried to execute a query to the table and surprisingly found that this time Hibernate was pointing to the right database/schema: DEV_DIG_UMT, the query failed because now the entity had the columns for the other database: DatDe001, see the log:
2013-08-15 14:50:05,731 TRACE tomcat-http--4 org.hibernate.engine.query.spi.QueryPlanCache - Located HQL query plan in cache (SELECT o FROM Sfitem o WHERE o.id.iisku = :iisku AND o.id.itemEffdt <= :date AND coalesce(o.itemExpdt, cast('9999-12-31' as date)) >= :date)
2013-08-15 14:50:05,766 TRACE tomcat-http--4 org.hibernate.engine.query.spi.QueryPlanCache - Located HQL query plan in cache (SELECT o FROM Sfitem o WHERE o.id.iisku = :iisku AND o.id.itemEffdt <= :date AND coalesce(o.itemExpdt, cast('9999-12-31' as date)) >= :date)
2013-08-15 14:50:05,768 TRACE tomcat-http--4 org.hibernate.engine.query.spi.HQLQueryPlan - Find: SELECT o FROM Sfitem o WHERE o.id.iisku = :iisku AND o.id.itemEffdt <= :date AND coalesce(o.itemExpdt, cast('9999-12-31' as date)) >= :date
2013-08-15 14:50:05,772 TRACE tomcat-http--4 org.hibernate.engine.spi.QueryParameters - Named parameters: {iisku=387671, date=2013-08-08}
2013-08-15 14:50:05,810 DEBUG tomcat-http--4 org.hibernate.SQL - select sfitem0_."iisku#" as iisku1_0_, sfitem0_."item_effdt" as item_eff2_0_, sfitem0_."created_at" as created_3_0_, sfitem0_."iidesc" as iidesc4_0_, sfitem0_."iipcst" as iipcst5_0_, sfitem0_."iivend" as iivend6_0_, sfitem0_."item_expdt" as item_exp7_0_ from sfitem sfitem0_ where sfitem0_."iisku#"=? and sfitem0_."item_effdt"<=? and coalesce(sfitem0_."item_expdt", cast('9999-12-31' as DATE))>=?
2013-08-15 14:50:05,832 DEBUG tomcat-http--4 org.hibernate.engine.jdbc.spi.SqlExceptionHelper - could not prepare statement [select sfitem0_."iisku#" as iisku1_0_, sfitem0_."item_effdt" as item_eff2_0_, sfitem0_."created_at" as created_3_0_, sfitem0_."iidesc" as iidesc4_0_, sfitem0_."iipcst" as iipcst5_0_, sfitem0_."iivend" as iivend6_0_, sfitem0_."item_expdt" as item_exp7_0_ from sfitem sfitem0_ where sfitem0_."iisku#"=? and sfitem0_."item_effdt"<=? and coalesce(sfitem0_."item_expdt", cast('9999-12-31' as DATE))>=?]
com.teradata.jdbc.jdbc_4.util.JDBCException: [Teradata Database] [TeraJDBC 14.00.00.21] [Error 3810] [SQLState 42S22] Column/Parameter 'DEV_DIG_UMT.sfitem0_.created_at' does not exist.
at com.teradata.jdbc.jdbc_4.util.ErrorFactory.makeDatabaseSQLException(ErrorFactory.java:307)
at com.teradata.jdbc.jdbc_4.statemachine.ReceiveInitSubState.action(ReceiveInitSubState.java:102)
at com.teradata.jdbc.jdbc_4.statemachine.StatementReceiveState.subStateMachine(StatementReceiveState.java:320)
at com.teradata.jdbc.jdbc_4.statemachine.StatementReceiveState.action(StatementReceiveState.java:201)
at com.teradata.jdbc.jdbc_4.statemachine.StatementController.runBody(StatementController.java:121)
at com.teradata.jdbc.jdbc_4.statemachine.StatementController.run(StatementController.java:112)
...
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$5.doPrepare(StatementPreparerImpl.java:161)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl$StatementPreparationTemplate.prepareStatement(StatementPreparerImpl.java:182)
at org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:159)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1859)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1836)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816)
at org.hibernate.loader.Loader.doQuery(Loader.java:900)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
at org.hibernate.loader.Loader.doList(Loader.java:2526)
at org.hibernate.loader.Loader.doList(Loader.java:2512)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342)
at org.hibernate.loader.Loader.list(Loader.java:2337)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495)
This means that hibernate validation and the query executor routines are behaving differently
The entity with the correct fields:
#Entity
public class Sfitem implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private SfitemPK id;
#Column(name="\"iidesc\"")
private String iidesc;
#Column(name="\"iipcst\"")
private BigDecimal iipcst;
#Column(name="\"iivend\"")
private BigDecimal iivend;
#Column(name="\"item_expdt\"")
private Date itemExpdt;
#Column(name="\"row_insrt_tms\"")
private Timestamp rowInsrtTms;
#Column(name="\"row_updt_tms\"")
private Timestamp rowUpdtTms;
...
}
Persistence.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.TeradataDialect"/>
<!-- value="create" to build a new database on each run; value="update" to modify an existing database; value="create-drop" means the same as "create" but also drops tables when Hibernate closes; value="validate" makes no changes to the database -->
<property name="hibernate.hbm2ddl.auto" value="validate"/>
<property name="hibernate.ejb.naming_strategy" value="org.hibernate.cfg.ImprovedNamingStrategy"/>
<property name="hibernate.connection.charSet" value="UTF-8"/>
<!-- Uncomment the following two properties for JBoss only -->
<!-- property name="hibernate.validator.apply_to_ddl" value="false" /-->
<!-- property name="hibernate.validator.autoregister_listeners" value="false" /-->
</properties>
</persistence-unit>
</persistence>
Datasource and entity manager beans:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="${datasource.jndiName}"/>
<property name="lookupOnStartup" value="true"/>
<property name="resourceRef" value="true" />
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="persistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
Is that a bug or a configuration issue? Has anyone faced this same issue?
I don't want to configure a default schema in the persistence unit nor in the entities, because the approach we are following is to keep the datasource configuration outside the application and in a single place by using the JNDI datasource defined in the container context. That way we don't need to worry when deploying to different environments (Dev, QA, Prod, etc)
You may need to fully qualify your table name in your SELECT queries that are being submitted to Teradata.
select sfitem0_."iisku#" as iisku1_0_, sfitem0_."item_effdt" as item_eff2_0_,
sfitem0_."created_at" as created_3_0_, sfitem0_."iidesc" as iidesc4_0_,
sfitem0_."iipcst" as iipcst5_0_, sfitem0_."iivend" as iivend6_0_,
sfitem0_."item_expdt" as item_exp7_0_
from DatDe001.SFITEM sfitem0_ /* Notice database name is included here */
where sfitem0_."iisku#"=?
and sfitem0_."item_effdt"<=?
and coalesce(sfitem0_."item_expdt", cast('9999-12-31' as DATE))>=?
Edit
You could also construct a string that you execute before each SELECT statement that specifies the schema/database you wish to use as the default database to be used to find objects that are not fully qualified in your SQL:
DATABASE=?
Then possibly use a parameter to provide that value like you are the values for your WHERE clause
Edit 2
You can only specify a single DATABASE parameter for a given connection string. If your requirement is to allow for different names for the database supporting the application front end you will need to parameterize the connection string for each database that the application will need to communicate with on the backend.
I'm trying to write a web service to store some data using jBoss 4.2.3 and Oracle.
I suppose to use Hibernate with CMT and seems to me it doesn't commit the transaction.
I have the following code:
Bean:
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
public class ZzzBean implements ZzzI {
public ZzzBean() {
}
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public int addZzz() {
try {
Zzz z = new Zzz();
z.setA("a");
z.setI(new BigDecimal(11));
HibernateUtil.getSessionFactory().getCurrentSession().save(z);
} catch (Exception ex) {
ex.printStackTrace();
}
return 1;
}
}
Interface:
#Local
public interface ZzzI {
int addZzz();
}
My session factory class:
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static Configuration configuration;
static {
try {
configuration = new AnnotationConfiguration().configure();
sessionFactory = configuration.buildSessionFactory();
} catch (Throwable ex) {
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
hibernate.cfg.xml has following:
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
<property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
<property name="hibernate.connection.url">jdbc:oracle:thin:#//my_host</property>
<property name="hibernate.connection.username">my_user</property>
<property name="hibernate.connection.password">my_pass</property>
<property name="show_sql">true</property>
<property name="current_session_context_class">jta</property>
<property name="transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<mapping resource="com/example/Zzz.hbm.xml" />
</session-factory>
Mapping file:
<hibernate-mapping>
<class name="com.example.Zzz" table="ZZZ">
<id name="i" type="big_decimal">
<column name="i" precision="22" scale="0" />
<generator class="assigned" />
</id>
<property name="a" type="string">
<column name="a" length="20" />
</property>
</class>
</hibernate-mapping>
Entity class:
#Entity
#Table(name = "ZZZ")
public class Zzz implements Serializable {
private static final long serialVersionUID = -4165930294512113400L;
private BigDecimal i;
private String a;
public Zzz(){}
#Id
#Column(name = "i", unique = true, nullable = false, precision = 22, scale = 0)
public BigDecimal getI() {
return this.i;
}
#Column(name = "a", length = 20)
public String getA() {
return this.a;
}
public void setI(BigDecimal i) {
this.i = i;
}
public void setA(String a) {
this.a = a;
}
}
And the web service code:
#WebService(name = "Zzz", serviceName = "Zzz")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#Stateless
public class ZzzWS {
#EJB(beanName = "ZzzBean")
ZzzI z;
#WebMethod
public int addZzz() {
return z.addVisit();
}
}
When I call web service method I have the following output:
13:43:52,671 INFO [Version] Hibernate Annotations 3.2.1.GA
13:43:52,682 INFO [Environment] Hibernate 3.2.4.sp1
13:43:52,686 INFO [Environment] hibernate.properties not found
13:43:52,687 INFO [Environment] Bytecode provider name : javassist
13:43:52,691 INFO [Environment] using JDK 1.4 java.sql.Timestamp handling
13:43:52,753 INFO [Configuration] configuring from resource: /hibernate.cfg.xml
13:43:52,753 INFO [Configuration] Configuration resource: /hibernate.cfg.xml
13:43:52,869 INFO [Configuration] Reading mappings from resource : com/example/Zzz.hbm.xml
13:43:52,884 INFO [Configuration] Configured SessionFactory: null
13:43:53,022 INFO [HbmBinder] Mapping class: com.example.Zzz -> ZZZ
13:43:53,124 INFO [DriverManagerConnectionProvider] Using Hibernate built-in connection pool (not for production use!)
13:43:53,124 INFO [DriverManagerConnectionProvider] Hibernate connection pool size: 20
13:43:53,124 INFO [DriverManagerConnectionProvider] autocommit mode: false
13:43:53,168 INFO [DriverManagerConnectionProvider] using driver: oracle.jdbc.OracleDriver at URL: jdbc:oracle:thin:#//my_host
13:43:53,168 INFO [DriverManagerConnectionProvider] connection properties: {user=***, password=***}
13:43:53,739 INFO [SettingsFactory] RDBMS: Oracle, version: Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options
13:43:53,739 INFO [SettingsFactory] JDBC driver: Oracle JDBC driver, version: 11.2.0.2.0
13:43:53,754 INFO [Dialect] Using dialect: org.hibernate.dialect.Oracle10gDialect
13:43:53,758 INFO [TransactionFactoryFactory] Transaction strategy: org.hibernate.transaction.CMTTransactionFactory
13:43:53,760 INFO [TransactionManagerLookupFactory] instantiating TransactionManagerLookup: org.hibernate.transaction.JBossTransactionManagerLookup
13:43:53,761 INFO [TransactionManagerLookupFactory] instantiated TransactionManagerLookup
13:43:53,761 INFO [SettingsFactory] Automatic flush during beforeCompletion(): disabled
13:43:53,761 INFO [SettingsFactory] Automatic session close at end of transaction: disabled
13:43:53,762 INFO [SettingsFactory] JDBC batch size: 15
13:43:53,762 INFO [SettingsFactory] JDBC batch updates for versioned data: disabled
13:43:53,762 INFO [SettingsFactory] Scrollable result sets: enabled
13:43:53,762 INFO [SettingsFactory] JDBC3 getGeneratedKeys(): disabled
13:43:53,762 INFO [SettingsFactory] Connection release mode: auto
13:43:53,763 INFO [SettingsFactory] Default batch fetch size: 1
13:43:53,763 INFO [SettingsFactory] Generate SQL with comments: disabled
13:43:53,763 INFO [SettingsFactory] Order SQL updates by primary key: disabled
13:43:53,763 INFO [SettingsFactory] Order SQL inserts for batching: disabled
13:43:53,763 INFO [SettingsFactory] Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
13:43:53,765 INFO [ASTQueryTranslatorFactory] Using ASTQueryTranslatorFactory
13:43:53,765 INFO [SettingsFactory] Query language substitutions: {}
13:43:53,765 INFO [SettingsFactory] JPA-QL strict compliance: disabled
13:43:53,765 INFO [SettingsFactory] Second-level cache: enabled
13:43:53,765 INFO [SettingsFactory] Query cache: disabled
13:43:53,765 INFO [SettingsFactory] Cache provider: org.hibernate.cache.NoCacheProvider
13:43:53,765 INFO [SettingsFactory] Optimize cache for minimal puts: disabled
13:43:53,765 INFO [SettingsFactory] Structured second-level cache entries: disabled
13:43:53,769 INFO [SettingsFactory] Echoing all SQL to stdout
13:43:53,769 INFO [SettingsFactory] Statistics: disabled
13:43:53,769 INFO [SettingsFactory] Deleted entity synthetic identifier rollback: disabled
13:43:53,769 INFO [SettingsFactory] Default entity-mode: pojo
13:43:53,769 INFO [SettingsFactory] Named query checking : enabled
13:43:53,789 INFO [SessionFactoryImpl] building session factory
13:43:54,121 INFO [SessionFactoryObjectFactory] Not binding factory to JNDI, no JNDI name configured
13:43:54,122 INFO [NamingHelper] JNDI InitialContext properties:{}
13:43:54,174 INFO [STDOUT] Hibernate: insert into ZZZ (a, i) values (?, ?)
But database does not have a new record even when I stop jBoss. Where is my fault? Please help.
P.S. When I am not using CMT and write code like:
tx = session.beginTransaction();
session.persist(...);
tx.commit();
all works fine.
I have found a solution: I moved database connection configuration from hibernate.cfg.xml to datasource (Z-ds.xml) and it works now. Of course this is not a normal solution of a problem, but a workaround. Thanks to all!