Спящий режим с объектами: исключение в потоке main org.hibernate.exception.GenericJDBCException: поле «department_id» не имеет значения по умолчанию

Рассмотрим классы:

Сотрудник.java

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue
    @Column(name="employee_id")
    private Long employeeId;

    @Column(name="firstname")
    private String firstname;

    @Column(name="lastname")
    private String lastname;

    @Column(name="birth_date")
    private Date birthDate;

    @Column(name="cell_phone")
    private String cellphone;

    @ManyToOne
    @JoinColumn(name="department_id", 
                insertable=false, updatable=false, 
                nullable=false)
    private Department department;

    public Employee() {

    }

    public Employee(String firstname, String lastname, String phone) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.birthDate = new Date(System.currentTimeMillis());
        this.cellphone = phone;
    }

    public Department getDepartment() {
        return department;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public Long getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Long employeeId) {
        this.employeeId = employeeId;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public String getCellphone() {
        return cellphone;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public void setCellphone(String cellphone) {
        this.cellphone = cellphone;
    }

}

Department.java

@Entity
@Table(name = "DEPARTMENT")
public class Department {

    @Id
    @Column(name="DEPARTMENT_ID")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long departmentId;

    @Column(name="DEPT_NAME")
    private String departmentName;

    @OneToMany(cascade={CascadeType.ALL})
    @JoinColumn(name="department_id")
    @IndexColumn(name="idx")
    private List<Employee> employees;

    public Long getDepartmentId() {
        return departmentId;
    }

    public void setDepartmentId(Long departmentId) {
        this.departmentId = departmentId;
    }

    public String getDepartmentName() {
        return departmentName;
    }

    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }

    public List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }
}

Основная программа

public class Main {

    private static final String FORNAME_URL = "com.mysql.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "root";
    private static final String DB_NAME = "MyHibernate";
    private static final String HIBERNATE_CFG = "hibernate.cfg.xml";

    /**
     * 
     * @param args
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public static void main(String[] args) throws ClassNotFoundException, SQLException {

        // create a DB 
        createDB();

        // first the HIBERNATE settings

        Configuration cfg = new Configuration().addResource(HIBERNATE_CFG).configure();
        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().
                applySettings(cfg.getProperties()).buildServiceRegistry();
        SessionFactory sessionFactory = cfg.buildSessionFactory(serviceRegistry);

        Session session = sessionFactory.openSession();
        session.beginTransaction();

        Department department = new Department();
        department.setDepartmentName("Sales");

        Employee emp1 = new Employee("Nina", "Mayers", "111");
        Employee emp2 = new Employee("Tony", "Almeida", "222");

        department.setEmployees(new ArrayList<Employee>());
        department.getEmployees().add(emp1);
        department.getEmployees().add(emp2);

        session.save(department);

        session.getTransaction().commit();
        session.close();
    }


    /**
     * Drop & Create a Database
     * Note that the DB name is above
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public static void createDB() throws SQLException, ClassNotFoundException 
    {
        try
        {
            Class.forName(FORNAME_URL);
            Connection connection = DriverManager.getConnection(URL , USERNAME , PASSWORD);
            Statement stmnt = connection.createStatement();

            // Drop & recreate DB 

            stmnt.executeUpdate("DROP DATABASE IF EXISTS " + DB_NAME);
            System.out.println("Database dropped successfully !");
            stmnt.executeUpdate("CREATE DATABASE IF NOT EXISTS " + DB_NAME); 
            System.out.println("The Database was created successfully !");

        }

        catch (SQLException s)
        {
            System.out.println("Problem creating DB");
        }

    }
}

И файл конфигурации:

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="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/MyHibernate</property>
        <property name="connection.username">root</property>
        <property name="connection.password">root</property>
        <property name="connection.pool_size">5</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
<mapping class="com.Department"></mapping>
<mapping class="com.Employee"></mapping>
</session-factory>
</hibernate-configuration>

Когда я запускаю основной класс, я получаю:

Exception in thread "main" org.hibernate.exception.GenericJDBCException: Field 'department_id' doesn't have a default value

а также :

INFO: HHH000262: Table not found: DEPARTMENT
Apr 12, 2014 12:08:59 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata
INFO: HHH000262: Table not found: EMPLOYEE
Apr 12, 2014 12:08:59 PM org.hibernate.tool.hbm2ddl.DatabaseMetadata getTableMetadata

Как я могу исправить эти исключения? все вроде нормально...

Кстати, я использую Hibernate 4.0

Спасибо


person JAN    schedule 12.04.2014    source источник
comment
Я некоторое время не использовал Hibernate. Существуют ли таблицы в БД? Можете ли вы попробовать запустить приложение, изменив hbm2ddl.auto на create в hibernate.cfg.xml?   -  person TomasZ.    schedule 12.04.2014
comment
@TomasZ.: Таблицы не существуют в БД, я использую Hibernate для их создания. Я пытался изменить auto на create, но получил Table 'myhibernate.department' doesn't exist.   -  person JAN    schedule 12.04.2014
comment
Попробуйте сначала закомментировать createDB(). Ваша схема должна существовать до того, как вы запустите свой код.   -  person TomasZ.    schedule 12.04.2014
comment
@TomasZ.: Я получаю то же, что и раньше ... спасибо   -  person JAN    schedule 12.04.2014
comment
Возможно, таблицы создаются после того, как он напечатает, что спящий режим их не нашел. Проблема может заключаться в том, что hibernate не генерирует идентификатор для отдела. Некоторая информация здесь stackoverflow.com/questions/11390445/ Попробуйте чтобы изменить свойство dialect на hibernate.dialect. Если это не сработает, попробуйте использовать @GenericGenerator, как в ссылке.   -  person TomasZ.    schedule 12.04.2014