MappingException: Unknown Entity on save() after migration


#1

Hi everyone,

This is probably a stupid mistake somewhere in my code but I’ve spent so much time and still haven’t found what is wrong, so here it goes.

I’m migrating a tool for automating prefetching in databases, so in the initialization, I am using a different type of configuration.
I migrated from Hibernate 3.2 to 4.3, and in order to test the changes for the migration I’m testing on a test project. For the old version, everything was working accordingly. Now, however, there seem to be something wrong with how the config reads the hibernate.cfg.xml, because it seems that my test entity cannot be found. I suspect that it might have something to do with the way I initialize the

I’m using the following configuration:
hibernate.cfg.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">Werty112</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="show_sql">true</property>
        <mapping resource="com/mkyong/common/Stock.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

Stock.java:

public class Stock implements java.io.Serializable {

	private static final long serialVersionUID = 1L;

	private Integer stockId;
	private String stockCode;
	private String stockName;


	public Stock() {
	}

	public Stock(String stockCode, String stockName) {
		this.stockCode = stockCode;
		this.stockName = stockName;
	}

	public Integer getStockId() {
		return this.stockId;
	}

	public void setStockId(Integer stockId) {
		this.stockId = stockId;
	}

	public String getStockCode() {
		return this.stockCode;
	}

	public void setStockCode(String stockCode) {
		this.stockCode = stockCode;
	}

	public String getStockName() {
		return this.stockName;
	}

	public void setStockName(String stockName) {
		this.stockName = stockName;
	}

}

Stock.hbg.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.mkyong.common.Stock" table="stock" catalog="sys">
        <id name="stockId" type="java.lang.Integer">
            <column name="STOCK_ID" />
            <generator class="identity" />
        </id>
        <property name="stockCode" type="string">
            <column name="STOCK_CODE" length="10" not-null="true" unique="true" />
        </property>
        <property name="stockName" type="string">
            <column name="STOCK_NAME" length="20" not-null="true" unique="true" />
        </property>
    </class>
</hibernate-mapping>

Main method:

    public static void main( String[] args )
    {
    	org.apache.log4j.BasicConfigurator.configure();
        System.out.println("Maven + Hibernate + MySQL");
        Session session = HibernateUtil.getSessionFactory().openSession();

        session.beginTransaction();
        Stock stock = new Stock();
        stock.setStockId(Integer.valueOf(1));
        stock.setStockCode("42");
        stock.setStockName("E");

        session.save(stock);  //breaks here
        session.getTransaction().commit();
        session.close();
    }
}

The initialization of the config:

public class HibernateUtil {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private static SessionFactory buildSessionFactory() {
        try {
            AutofetchConfiguration cfg = (AutofetchConfiguration) new AutofetchConfiguration();
            cfg.addClass(Stock.class);
            cfg.addClass(com.mkyong.common.Stock.class);
            cfg.configure();
            StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties());
            ExtentManager extentManager = new ExtentManager();
            ssrb.addService(EventListenerRegistry.class, new AutofetchEventListenerRegistryImpl(extentManager));
            return cfg.buildSessionFactory(ssrb.build(), extentManager);
        }
        catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void shutdown() {
    	// Close caches and connection pools
    	getSessionFactory().close();
    }

}

The error:

Exception in thread "main" org.hibernate.MappingException: Unknown entity: com.mkyong.common.Stock
	at org.hibernate.internal.SessionFactoryImpl.getEntityPersister(SessionFactoryImpl.java:1096)
	at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1479)
	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:117)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:209)
	at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:194)
	at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
	at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
	at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:715)
	at org.hibernate.internal.SessionImpl.save(SessionImpl.java:707)
	at org.hibernate.internal.SessionImpl.save(SessionImpl.java:702)
	at com.mkyong.common.App.main(App.java:20)

Does anyone have an idea what could be wrong here?
Thanks in advance.

UPDATE:
I have tried reverting to the normal configuration, and that works. So there are some errors in the AutofetchConfiguration apparently. Anyone who might have ideas about what could be wrong with the configuration-class if the entities are not stored properly?


#2

This was solved by adding the call to add(resource) which was missing before. Now it finds the mappings correctly :slightly_smiling_face:


#3

even my code breaks at session.save could u show me the place where u made the changes…