Search code examples
javahibernateexceptioninheritanceannotations

single table inheritance in hibernate showing SQL grammar exception


I am trying to implement inheritance using hibernate and using simple program

Well I am declaring a class of person having four attributes-age,sex,name,id(which is auto generated)

Now I have two classes inheriting the base class

The first class is native where one attribute is there that defines pincode whereas the other class is foreign where psotcode is defined

Following is my whole code

person.java

package com;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Person {
    private String Name;
    private int age;
    private String sex;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private String id;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

native.java

package com;

import javax.persistence.Entity;

@Entity
public class Native extends Person {
    private int pincode;

    public int getPincode() {
        return pincode;
    }

    public void setPincode(int pincode) {
        this.pincode = pincode;
    }
}


foreign.java

package com;

import javax.persistence.Entity;

@Entity
public class Foreign extends Person {
    private String postcode;

    public String getPostcode() {
        return postcode;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }
}

mainclass.java

package com;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class Classmain {
    public static void main(String args[])

    {
        Person person = new Person();
        person.setName("krish");
        person.setSex("M");
        person.setAge(23);

        Native native = new Native();
        native.setPincode(201545);
        native.setAge(23);
        native.setName("victor");
        native.setSex("M");

        Foreign foreign = new Foreign();
        foreign.setPostcode("sfadfas0");
        foreign.setName("michelle");
        foreign.setAge(31);
        foreign.setSex("F");


        SessionFactory sessionfactory = new AnnotationConfiguration()
                .configure().buildSessionFactory();
        Session session = sessionfactory.openSession();
        session.beginTransaction();
        session.save(person);
        session.save(foreign);
        session.save(native);
        session.getTransaction().commit();
        session.close();

    }
}

Following is my 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>
        <!-- Database connection settings -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/Inherit1</property>
        <property name="connection.username">root</property>
        <property name="connection.password">vvvvvvvv</property>
        <property name="hbm2ddl.auto">update</property>


        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>


        <mapping class="com.Person" />
        <mapping class="com.Native" />
        <mapping class="com.Foreign" />

    </session-factory>
</hibernate-configuration>

However I am getting the following error

INFO: HHH000232: Schema update complete
Hibernate: insert into Person (Name, age, sex, DTYPE) values (?, ?, ?, 'Person')
Jun 7, 2013 7:12:30 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1146, SQLState: 42S02
Jun 7, 2013 7:12:30 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Table 'Inherit1.Person' doesn't exist
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute statement
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:123)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
    at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:96)
    at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:58)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2975)
    at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3487)
    at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:81)
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377)
    at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:214)
    at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:194)
    at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:178)
    at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:321)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:286)
    at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:192)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:125)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
    at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
    at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
    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:764)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
    at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
    at com.Classmain.main(Classmain.java:33)
Caused by: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Table 'Inherit1.Person' doesn't exist
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
    at com.mysql.jdbc.Connection.execSQL(Connection.java:3283)
    at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1332)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1604)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1519)
    at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1504)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
    ... 22 more

What could be the reason?


Solution

  • OK, I found your error, but you should have seen in your logs the previous errors:

    ERROR: HHH000389: Unsuccessful: create table Person (DTYPE varchar(31) not null, id varchar(255) not null auto_increment, Name varchar(255), age integer not null, sex varchar(255), pincode integer, postcode varchar(255), primary key (id))
    07-jun-2013 17:17:35 org.hibernate.tool.hbm2ddl.SchemaExport perform
    ERROR: Incorrect column specifier for column 'id'
    

    If you look at the definition of id, you are trying to declare an auto-increment field with a String variable in Person class. Change it with int and it will work perfectly.

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    

    A unique table named Person is created and data are inserted correctly.