I'm attempting to create a Developer Class that extends an Employee Class and create a table for the Developer class in my Database by adding the mapping to my Employee.hbm.xml file.
public class Employee {
private int emp_no;
private String firstname;
private String lastname;
private int age;
public Employee(){};
public Employee(int emp_no, String firstname, String lastname, int age) {
this.emp_no = emp_no;
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
}
}
public class Developer extends Employee{
private String specialty;
private String level;
private int devId =0;
public Developer(){
super();
}
public Developer(int emp_no, String firstname, String lastname, int age) {
super(emp_no, firstname, lastname, age);
}
public void insertDeveloper(){
OracleDAO.saveObject(this);
}
}
Oracle DAO takes an object and persists it to the database.
public class OracleDAO {
public static Session getSession(){
Configuration cfg = new Configuration().configure();
Session session= cfg.buildSessionFactory().openSession();
return session;
}
public static void saveObject(Object obj) {
Configuration cfg= new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();
Transaction txn = session.getTransaction();
try{
txn.begin();
session.save(obj);
session.flush();
txn.commit();
session.close();
}catch(HibernateException e){
e.printStackTrace();
txn.rollback();
}
}
}
I am recreating the database every time I run my code. My hibernate.hbm.xml file has these in them:
<property name="hbm2ddl.auto">create</property>
<mapping resource="Employee.hbm.xml"/>
My Employee.hbm.xml file looks like this:
<hibernate-mapping>
<class name="com.eintern.hibernate.Employee" table="einternEmployees">
<id name="emp_no" column="id">
<generator class="increment"/>
</id>
<property name="firstname"/>
<property name="lastname"/>
<property name="age"/>
<joined-subclass name="com.eintern.hibernate.Developer">
<key column="eid"></key>
<property name="specialty"></property>
<property name="level"></property>
</joined-subclass>
</class>
My main class looks like this:
public class TestEmployee {
ArrayList<Employee> myEmployeeList;
public TestEmployee(){}
public TestEmployee(ArrayList<Employee> myEmployeeList) {
this.myEmployeeList = myEmployeeList;
}
public ArrayList<Employee> getMyEmployeeList() {
return myEmployeeList;
}
public void setMyEmployeeList(ArrayList<Employee> myEmployeeList) {
this.myEmployeeList = myEmployeeList;
}
/**Takes a String of the filename
* Returns an ArrayList of Employee Objects
* @param dataFile
* @return
*/
public void fileToEmployee(String dataFile){
BufferedReader br = null;
ArrayList<String[]> myStringArray = new ArrayList<String[]>();
ArrayList<Employee> myEmployees;
Class creatingEmployeeRef;
Employee creatingEmployee;
try{
myEmployees = new ArrayList<Employee>();
String sCurrentLine;
br = new BufferedReader(new FileReader(dataFile));
while((sCurrentLine = br.readLine())!=null){
myStringArray.add(sCurrentLine.split(","));
}
for(int i = 0; i<myStringArray.size(); i++){
creatingEmployeeRef = Class.forName("com.eintern.hibernate.Employee");
creatingEmployee = (Employee)creatingEmployeeRef.newInstance();
String[] currentIt = myStringArray.get(i);
for(int j =0; i<currentIt.length;j++){
if(j ==0){
creatingEmployee.setEmp_no(Integer.parseInt(currentIt[j]));
System.out.println(Integer.parseInt(currentIt[j]));
}else if(j==1){
creatingEmployee.setFirstname(currentIt[j]);
System.out.println(currentIt[j]);
}else if(j==2){
creatingEmployee.setLastname(currentIt[j]);
System.out.println(currentIt[j]);
}else if(j==3){
creatingEmployee.setAge(Integer.parseInt(currentIt[j]));
System.out.println(currentIt[j]);
}else{
break;
}
}
myEmployees.add(creatingEmployee);
}
this.myEmployeeList = myEmployees;
}catch(IOException e){
e.printStackTrace();
}catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try{
if(br!=null)br.close();
}catch(IOException ex){
ex.printStackTrace();
}
}
}
/**
* Takes an employee object
* Returns true if employee successfully entered into the DB
* @param oneEmployee
* @return
*/
public boolean insertEmployee(){
for(Employee testEmployee:this.getMyEmployeeList()){
OracleDAO.saveObject(testEmployee);
/*System.out.println(testEmployee.getEmp_no());
System.out.println(testEmployee.getFirstname());
System.out.println(testEmployee.getLastname());
System.out.println(testEmployee.getAge());*/
}
return false;
}
public static void main(String[] args) {
/*Employee employeeObject = new Employee();
employeeObject.setEmp_no(1);
employeeObject.setFirstname("Jesse");
employeeObject.setLastname("Lawson");
employeeObject.setAge(40);
*/
/*OracleDAO myO = new OracleDAO();
myO.saveObject(employeeObject);
*/
/*TestEmployee myTest = new TestEmployee();
myTest.fileToEmployee("data.txt");
myTest.insertEmployee();*/
//Employee myDeveloper = new Employee(60,"Vlad","Gudzuk",27);
TestEmployee testDeveloper = new TestEmployee();
ArrayList<Employee> tempArrayList = new ArrayList<Employee>();
//tempArrayList.add(myDeveloper);
//testDeveloper.setMyEmployeeList(tempArrayList);
//testDeveloper.insertEmployee();
Developer myDev = new Developer(70,"Justin","Roberson",21);
myDev.setLevel("Entry");
myDev.setSpecialty("HTML");
myDev.insertDeveloper();
/*Employee myDevEmp = (Employee)myDev;
TestEmployee myTest = new TestEmployee();
ArrayList<Employee> myEmpArray = new ArrayList<Employee>();
myEmpArray.add(myDevEmp);
myTest.setMyEmployeeList(myEmpArray);
myTest.insertEmployee();
/*myDev.setSpecialty("HTML");
myDev.setLevel("Entry");
myDev.insertDeveloper();
/*
myDeveloper.setLevel("Entry");
myDeveloper.setSpecialty("HTML");
myDeveloper.insertDeveloper();
*/
}
}
The hibernate says it puts it in (which it doesn't) and it also returns this error code from the OracleDAO in the catch block HibernateException:
Hibernate: select max(id) from einternEmployees
Hibernate: insert into einternEmployees (firstname, lastname, age, id) values (?, ?, ?, ?) Hibernate: insert into Developer (specialty, level, eid) values (?, ?, ?) org.hibernate.exception.SQLGrammarException: could not insert: [com.eintern.hibernate.Developer] at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92) at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2455) at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2875) at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79) at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265) at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184) at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321) at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51) at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) at com.eintern.hibernate.OracleDAO.saveObject(OracleDAO.java:33) at com.eintern.hibernate.Developer.insertDeveloper(Developer.java:35) at com.eintern.hibernate.TestEmployee.main(TestEmployee.java:140) Caused by: java.sql.SQLException: ORA-01747: invalid user.table.column, table.column, or column specification
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:331)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:288)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:743)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:216)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:955)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1169)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3285)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3368)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2438)
... 11 more
Final Notes:
I realize my code can use a little clean up. If you need me to clarify anything please ask. The code works when I am creating an Employee object and I feed the object to OracleDAO (It creates the Employee table in my Database), but it doesn't work when I create a Developer object and feed it to OracleDAO(It doesn't create the Developer table in my database). It doesn't even work when I create a Developer object and cast it to an Employee object and feed it to the OracleDAO.
My next steps may be to create a Developer.hbm.xml file and add a to the Employee.hbm.xml file, but I'd like to understand how to do it this way if possible. Any help or thoughts is much appreciated. Thanks in advanced.
OracleDaothe developer object is cast toEmployeewhich is the top class in the hierarchy - when saving anEmployeethe fields ofDeveloperare ignored. I also have a similar case and to enure the subclass is properly saved I call the subclass Dao explicitly.