[solved] Missing table, mix entity tables with persistence Units


#1

hi, im having this exact problem

any solution without removing the property? as its a good sanity check and i dont want to remove it

it works fine with hibernate 3.3.1GA, but now im migrating/updating to 5.2.12.FINAL and the problem occurs


#2

I answered your question on StackOverflow.


#3

thanks a lot for reply, i will try to give you more information so you can help me please

i dont have enough reputation in S.O. to comment so i reply here.

A JPA EntityManager belongs to one persistence unit, or EntityManagerFactory, You can’t mix multiple persistence units with the same EntityManager.

I understand that, i have been using multiple PU to access multiple databases many years but with lower versions of hibernate. im not doing that mix

You can have a single persistence unit and use the schema attribute when mapping entities.

i prefeer to have different persistence units, because one is only for reading data of another system, the other is saving data to the current system that does some analytics, and other is exporting some data to a third server database, so its much clear to separate the PU

you use multiple persistence units, you need multiple persistence.xml, multiple EntityManagerFactory and probably JTA if you need to global transaction

i have been using with older versions of hibernate, the same persistence.xml file but it declares the differents PU inside with success and with the property validate activated. do you mean creating two or more files? something like persistence1.xml persistence2.xml ?

which will be the difference if each PU is declared as a tag

here is an example (not the real case as it have a lot of entities) of my file

<?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="PU_A" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>app.layer.dl.model.EntityA</class>
    <properties>
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.use_query_cache" value="false"/>
      <property name="hibernate.cache.provider_class" value=""/>
      <property name="hibernate.connection.verifyServerCertificate" value="false"/>
      <property name="hibernate.connection.useSSL" value="false"/>
      <property name="javax.persistence.jdbc.url" value=""/>
      <property name="javax.persistence.jdbc.user" value=""/>
      <property name="javax.persistence.jdbc.driver" value=""/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
  <persistence-unit name="PU_B" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>app.layer.dl.model.waldbott.EntityB</class>
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
      <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
      <property name="hibernate.cache.use_query_cache" value="false"/>
      <property name="hibernate.connection.verifyServerCertificate" value="false"/>
      <property name="hibernate.connection.useSSL" value="false"/>
      <property name="javax.persistence.jdbc.url" value=""/>
      <property name="javax.persistence.jdbc.user" value=""/>
      <property name="javax.persistence.jdbc.driver" value=""/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
  <persistence-unit name="cloud_PU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>ar.com.xxx.pedidosCloud.model_cloud.EntityCloud</class>
    <properties>
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.use_query_cache" value="false"/>
      <property name="hibernate.connection.verifyServerCertificate" value="false"/>
      <property name="hibernate.connection.useSSL" value="false"/>
      <property name="javax.persistence.jdbc.url" value=""/>
      <property name="javax.persistence.jdbc.user" value=""/>
      <property name="javax.persistence.jdbc.driver" value=""/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
</persistence>

the problem is that when i create the EMF for the PU_A it gives an error like

caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [EntityB]

but it doesnt have to check entity B as its not declared in PU_A!! and the same code works with the older hibernate version


#4

How do you create the EMF? Add the code and the entire stacktrace.


#5

its part of a big code, so ill try to extract what is important

the string PU is the string declared in the tag mentioned before, and propertyes its just the map with some propertied added for example the property in trouble hibernate.hbm2ddl.auto

the real important line is

emf = Persistence.createEntityManagerFactory(PU,propertiesDB);

the test connection (jdbc) is passing ok.

    private void createEntityManagerFactory(String PU) throws Exception
    {
        switch (PU) {
            case ConfigPersistence.DB1_PU:
                if (!errorDB) {
                    if ( (emf != null) && (emf.isOpen()) ) {
                        emf.close();
                    }
                }
                eFLogger.debug("*****************PARAMs *************************\n"+propertiesDB.get("hibernate.connection.username")+
                                  " "+propertiesDB.get("hibernate.connection.password")+" "+
                                  propertiesDB.get("hibernate.connection.url")+"\n*****************PARAMs*************************");
                if (testConnection( ConfigPersistence.getDBuser(), 
                                    ConfigPersistence.getDBpass(), 
                                    ConfigPersistence.getDBserverIP(), 
                                    ConfigPersistence.getDBserverPort(), 
                                    ConfigPersistence.getDBInstanceName(),
                                    ConfigPersistence.getDBName(),
                                    ConfigPersistence.DB_DRIVER
                                    )
                   ) { 
                    
                    emf = Persistence.createEntityManagerFactory(PU,propertiesDB);
                }
                 else {
                    throw new Exception();
                }
                break;
            case ConfigPersistence.DB2_PU:
                if (!errorDB2) {
                    if ( (emfDB2 != null) && (emfDB2.isOpen()) ) {
                        emfDB2.close();
                    }
                }
                eFLogger.debug("*****************PARAMs DB2*************************\n"+propertiesDB2.get("hibernate.connection.username")+
                                    " "+propertiesDB2.get("hibernate.connection.password")+" "+
                                    propertiesDB2.get("hibernate.connection.url")+"\n*****************PARAMs*************************");
                if (testConnection(  ConfigPersistence.getDB2user(), 
                                     ConfigPersistence.getDB2pass(), 
                                     ConfigPersistence.getDB2serverIP(), 
                                     ConfigPersistence.getDB2serverPort(), 
                                     ConfigPersistence.getDB2InstanceName(),
                                     ConfigPersistence.getDB2Name(),
                                     ConfigPersistence.DB2_DRIVER
                        ))
                {
                     emfDB2 = Persistence.createEntityManagerFactory(PU, propertiesDB2);
                }
                else {
                     throw new Exception();
                 }
                break;
        }

    }//createEntityManagerFactory

here goes the stack

STACK: 
------
javax.persistence.PersistenceException: [PersistenceUnit: fw_PU] Unable to build Hibernate SessionFactory
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:970)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:895)
	at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at app.layer.dal.impl.ControllerDal.createEntityManagerFactory(ControllerDal.java:661)
	at app.layer.dal.impl.ControllerDal.initPersistence(ControllerDal.java:626)
	at app.Controller.initAplicationEnterprise(Controller.java:274)
	at app.layer.pl.view.swing.core.EnterpriseChooserDialog.chooseEnterprise(EnterpriseChooserDialog.java:204)
	at app.layer.pl.view.swing.core.EnterpriseChooserDialog.access$200(EnterpriseChooserDialog.java:25)
	at app.layer.pl.view.swing.core.EnterpriseChooserDialog$4.efDoBK(EnterpriseChooserDialog.java:176)
	at app.util.EFTaskDialog$EFSwingWorker.doInBackground(EFTaskDialog.java:36)
	at app.util.EFTaskDialog$EFSwingWorker.doInBackground(EFTaskDialog.java:22)
	at javax.swing.SwingWorker$1.call(SwingWorker.java:295)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at javax.swing.SwingWorker.run(SwingWorker.java:334)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing table [ARTICULO]
	at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateTable(AbstractSchemaValidator.java:121)
	at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:42)
	at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89)
	at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:191)
	at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:312)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:460)
	at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:892)
	... 16 more
------

:::::::::::::::::::::::********************:::::::::::::::::::::

note that in the real escenario the missing table is ARTICULO, but believe me its declared in the other PU inside the persistence.xml i think it coul be an hibernate bug, since it works with the older version mentioned in the first post


#6

here the real persistence.xml so you can check that [PersistenceUnit: fw_PU] does not contain the class articulo, which table fails

<?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="fw_PU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>app.layer.dl.model.Configuracion</class>
    <class>app.layer.dl.model.Roles</class>
    <class>app.layer.dl.model.RolesPermissions</class>
    <class>app.layer.dl.model.User</class>
    <class>app.layer.dl.model.deposito.CajaEntrante</class>
    <class>app.layer.dl.model.deposito.CajasCompuestasEntrada</class>
    <class>app.layer.dl.model.deposito.CajasCompuestasPedido</class>
    <class>app.layer.dl.model.deposito.Comisionista</class>
    <class>app.layer.dl.model.deposito.PalesEntrantes</class>
    <class>app.layer.dl.model.deposito.PalesPedido</class>
    <class>app.layer.dl.model.deposito.PersonalDeposito</class>
    <class>app.layer.dl.model.deposito.Recepciones</class>
    <class>app.layer.dl.model.deposito.Receptor</class>
    <class>app.layer.dl.model.deposito.RemitoCliente</class>
    <class>app.layer.dl.model.deposito.TransportePropio</class>
    <class>app.layer.dl.model.deposito.VendedorBlacklist</class>
    <class>app.layer.dl.model.deposito.Envio</class>
    <class>app.layer.dl.model.pedidos.DescuentoXCliente</class>
    <class>app.layer.dl.model.pedidos.Descuentos</class>
    <class>app.layer.dl.model.pedidos.ItemsPedido</class>
    <class>app.layer.dl.model.pedidos.Pedido</class>
    <class>app.layer.dl.model.pedidos.PedidosImpresos</class>
    <class>app.layer.dl.model.pedidos.PedidosMakers</class>
    <class>app.layer.dl.model.trazabilidad.ErroresWebService</class>
    <class>app.layer.dl.model.trazabilidad.Informes</class>
    <class>app.layer.dl.model.trazabilidad.RenglonInforme</class>
    <class>app.layer.dl.model.trazabilidad.SeriesBlacklist</class>
    <class>app.layer.dl.model.bancos.Chequera</class>
    <class>app.layer.dl.model.bancos.Depositos</class>
    <class>app.layer.dl.model.bancos.Emisiones</class>
    <class>app.layer.dl.model.bancos.FacturasCheque</class>
    <class>app.layer.dl.model.bancos.SaldoBancos</class>
    <class>app.layer.dl.model.bancos.Talonarios</class>
    <class>app.layer.dl.model.bombas.Asignaciones</class>
    <class>app.layer.dl.model.bombas.Bomba</class>
    <class>app.layer.dl.model.bombas.EnReparacion</class>
    <class>app.layer.dl.model.bombas.InformeR</class>
    <class>app.layer.dl.model.bombas.Ingreso</class>
    <class>app.layer.dl.model.bombas.NrosComodatosLidus</class>
    <class>app.layer.dl.model.bombas.TipoBomba</class>
    <class>app.layer.dl.model.ArticulosCertificados</class>
    <properties>
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.use_query_cache" value="false"/>
      <!-- Los comento porque en este proyecto se setean por codigo en el Controller DAL
      <property name="hibernate.cache.provider_class" value=""/>
      <property name="hibernate.connection.verifyServerCertificate" value="false"/>
      -->
      <property name="hibernate.connection.useSSL" value="false"/>
      <property name="javax.persistence.jdbc.url" value=""/>
      <property name="javax.persistence.jdbc.user" value=""/>
      <property name="javax.persistence.jdbc.driver" value=""/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
  <persistence-unit name="fw_PUDB2" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>app.layer.dl.model.waldbott.ClientesWaldbott</class>
    <class>app.layer.dl.model.waldbott.Ctacli</class>
    <class>app.layer.dl.model.waldbott.Tablas</class>
    <class>app.layer.dl.model.waldbott.Valor</class>
    <class>app.layer.dl.model.waldbott.Vendedor</class>
    <class>app.layer.dl.model.waldbott.Movfdosc</class>
    <class>app.layer.dl.model.waldbott.Movfdosi</class>
    <class>app.layer.dl.model.waldbott.Proveedo</class>
    <class>app.layer.dl.model.waldbott.Despacho</class>
    <class>app.layer.dl.model.waldbott.Emailsclte</class>
    <class>app.layer.dl.model.waldbott.Itcabeza</class>
    <class>app.layer.dl.model.waldbott.Ititems</class>
    <class>app.layer.dl.model.waldbott.Listas</class>
    <class>app.layer.dl.model.waldbott.Occabeza</class>
    <class>app.layer.dl.model.waldbott.Ocitems</class>
    <class>app.layer.dl.model.waldbott.Pdcabeza</class>
    <class>app.layer.dl.model.waldbott.Pditems</class>
    <class>app.layer.dl.model.waldbott.Stocks</class>
    <class>app.layer.dl.model.waldbott.Articulo</class>
    <!--	enable	selective	2nd	level	cache	-->
    <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
    <properties>
      <!--	configure	caching	-->
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
      <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>
      <property name="hibernate.cache.use_query_cache" value="false"/>
      <!-- Los comento porque en este proyecto se setean por codigo en el Controller DAL
      <property name="hibernate.connection.verifyServerCertificate" value="false"/>
      <property name="hibernate.connection.useSSL" value="false"/>
      -->
      <property name="javax.persistence.jdbc.url" value=""/>
      <property name="javax.persistence.jdbc.user" value=""/>
      <property name="javax.persistence.jdbc.driver" value=""/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
  <persistence-unit name="cloud_PU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>ar.com.eeffsoft.pedidosCloud.model_cloud.ArticuloCloud</class>
    <class>ar.com.eeffsoft.pedidosCloud.model_cloud.ClientesCloud</class>
    <class>ar.com.eeffsoft.pedidosCloud.model_cloud.ConfCloud</class>
    <class>ar.com.eeffsoft.pedidosCloud.model_cloud.ItemsPedidoCloud</class>
    <class>ar.com.eeffsoft.pedidosCloud.model_cloud.PedidoCloud</class>
    <properties>
      <property name="hibernate.cache.use_second_level_cache" value="false"/>
      <property name="hibernate.cache.use_query_cache" value="false"/>
      <!-- Los comento porque en este proyecto se setean por codigo en el Controller DAL
      <property name="hibernate.connection.verifyServerCertificate" value="false"/>
      <property name="hibernate.connection.useSSL" value="false"/>
      -->
      <property name="javax.persistence.jdbc.url" value=""/>
      <property name="javax.persistence.jdbc.user" value=""/>
      <property name="javax.persistence.jdbc.driver" value=""/>
      <property name="javax.persistence.jdbc.password" value=""/>
    </properties>
  </persistence-unit>
</persistence>

here is the entity



package app.layer.dl.model.waldbott;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.UniqueConstraint;
import javax.xml.bind.annotation.XmlRootElement;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;



@Entity
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Table(name = "ARTICULO", uniqueConstraints = {
    @UniqueConstraint(columnNames = {"FACTURABLE", "NUMERO"})})
@XmlRootElement

public class Articulo implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @Column(name = "NUMERO", nullable = false, length = 20)
    private String numero;
    @Column(name = "DESCRIP", length = 50)
    private String descrip;
    @Column(name = "EQUIVALENC", length = 9)
    private String equivalenc;
    @Column(name = "AGRUPMIEN", length = 20)
    private String agrupmien;
    @Column(name = "CODBARRAS", length = 18)
    private String codbarras;
 .
.
.
.
.



#7

But tables are associated with a PU and cannot reference tables from other PU. If it worked in 3.x, it might have been by accident.

You need to change the configuration and make sure all related associations are colocared in the same PU.


#8

i dont undestand wich is my mistake, could you explain me a bit more?

table ARTICULO form Entity
Public class Articulo implements Serializable
is only asociated with fw_PUDB2
and its failing in EMF creation of the other PU (the fw_PU), and im not referencing a table of the other PU

im not mixing things,

there is no mixing associations as the models are autogenerated by netbeans IDE from the databases


#9

Try to debug it and see what it’s causing the issue. It might be a bug. To be sure, better debug the Hibernate code. That’s the beauty of open source.


#10

ok i will try to debug, do you want me to write a small POC project with DatabaseA EntityA TableA PUA EMFA and DatabaseB EntityB TableB PUB EMFB where it fails?


#11

Sure. You can use this test case templates:

http://in.relation.to/2016/01/14/hibernate-jpa-test-case-template/


#12

is ok that catalog ans chema is null here? im not specifyng the schema in the entity because it changes in development and in production and its the same code


#13


#14

table ARTICULO must not be evaluated here, since im the creation of the PU that has not asignated ARTICULO


#15

so in AbstractSchemaValidator.Java here is the ex beacuse tableInformation=null


#16

@vlad here is the POC in a little maven project


#17

You need to create a Jira issue and attach the test case. Thanks.


#18

DONE, https://hibernate.atlassian.net/browse/HHH-12450


#19

Looks like both persistence units are scanning the same packages…

Note that in Java SE environments, a list of all named managed persistence classes must be specified… (as you have shown in later post but you forgot <exclude-unlisted-classes>), and I have seen some reports of problem with versions of Hibernate not supporting correctly <exclude-unlisted-classes> in SE env, so maybe you are hitting that one too.


#20

so i must cancel the bug report? property is false?