Hibernate继承映射:每个子类的表

时间:2015-07-20 03:55:19

标签: java oracle hibernate

我试图通过将映射添加到我的Employee.hbm.xml文件来创建扩展Employee类并为我的数据库中的Developer类创建表的Developer类。

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获取一个对象并将其持久保存到数据库中。

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();
    }

  }
}

每次运行代码时,我都在重新创建数据库。我的hibernate.hbm.xml文件包含以下内容:

<property name="hbm2ddl.auto">create</property>

    <mapping resource="Employee.hbm.xml"/>

我的Employee.hbm.xml文件如下所示:

<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>

我的主要课程如下:

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();
*/

}

}

hibernate说它把它放入(它没有)并且它也从catch块HibernateException中的OracleDAO返回这个错误代码:

Hibernate: select max(id) from einternEmployees

Hibernate:插入einternEmployees(firstname,lastname,age,id)值(?,?,?,?) Hibernate:插入Developer(专业,级别,eid)值(?,?,?) org.hibernate.exception.SQLGrammarException:无法插入:[com.eintern.hibernate.Developer]     在org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:92)     在org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2455)     在org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2875)     在org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)     在org.hibernate.engine.ActionQueue.execute(ActionQueue.java:273)     在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:265)     在org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:184)     在org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)     在org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)     在org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216)     at com.eintern.hibernate.OracleDAO.saveObject(OracleDAO.java:33)     在com.eintern.hibernate.Developer.insertDeveloper(Developer.java:35)     在com.eintern.hibernate.TestEmployee.main(TestEmployee.java:140) 引起:java.sql.SQLException:ORA-01747:user.table.column,table.column或列规范无效

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

最后的笔记:

我意识到我的代码可以使用一点点清理。如果您需要我澄清一切,请询问。当我创建一个Employee对象并将对象提供给OracleDAO(它在我的数据库中创建Employee表)时,代码可以工作,但是当我创建一个Developer对象并将其提供给OracleDAO时,它不起作用(它没有& #39;在我的数据库中创建Developer表。当我创建一个Developer对象并将其转换为Employee对象并将其提供给OracleDAO时,它甚至无法工作。

我接下来的步骤可能是创建一个Developer.hbm.xml文件并将其添加到Employee.hbm.xml文件中,但是如果可能的话,我想了解如何以这种方式执行此操作。非常感谢任何帮助或想法。谢谢你提前。

1 个答案:

答案 0 :(得分:1)

解决方案相当简单 - 不要使用Oracle Reserved Words作为列名。

private String level;

LEVEL就是其中之一,所以很简单就将它映射到另一个column_name。

有点副作用是Hibernate甚至因为保留列名而无法创建表DELEVOPER。

create table Developer (eid number(10,0) not null, specialty varchar2
(255 char), level varchar2(255 char), primary key (eid));


    ORA-00904: : invalid identifier

..但是简单地忽略了异常,假设表已经存在且因此无法创建

 -- ORA-00955: name is already used by an existing object

<强>更新

错误ORA-01747:无效的user.table.column,table.column或列规范在插入时触发,但在查询表时触发。 解释是,甚至在数据字典表定义之前检查保留字。您可以通过以下方式验证这一点:

SELECT  
  employee0_1_.level      AS level3_0_ 
from missing_table employee0_

即使指定的表不存在,也会引发 ORA-01747:无效的user.table.column,table.column或列规范