简体   繁体   中英

How the relationships between tables in JPA are setted?

I got the error:

Unknown column 'employee0_2_.employee_id' in 'field list'

What is the problem with my fields? What is missing?

Full stack trace:

Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1316)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:898)
at tests.ApplTest.main(ApplTest.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.hibernate.exception.SQLGrammarException: could not extract ResultSet
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:82)
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.extract(ResultSetReturnImpl.java:61)
at org.hibernate.loader.Loader.getResultSet(Loader.java:2040)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1837)
at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816)
at org.hibernate.loader.Loader.doQuery(Loader.java:900)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:312)
at org.hibernate.loader.Loader.loadEntity(Loader.java:2121)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:82)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:72)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3927)
at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:460)
at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:429)
at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:206)
at org.hibernate.event.internal.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:262)
at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:150)
at org.hibernate.internal.SessionImpl.fireLoad(SessionImpl.java:1092)
at org.hibernate.internal.SessionImpl.access$2000(SessionImpl.java:175)
at org.hibernate.internal.SessionImpl$IdentifierLoadAccessImpl.load(SessionImpl.java:2476)
at org.hibernate.internal.SessionImpl.get(SessionImpl.java:992)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:271)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:151)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:76)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:914)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:898)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:902)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:889)
... 6 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'employee0_2_.employee_id' in 'field list'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3491)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3423)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1936)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2060)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2542)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1734)
at com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1885)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56)

MySql Table:

CREATE TABLE Employee(employee_id INTEGER PRIMARY KEY NULL , name VARCHAR(50) UNIQUE NULL , salary VARCHAR(50) null , specialization VARCHAR(50) NULL);
CREATE TABLE Managers(name  VARCHAR(50) NULL UNIQUE , lastname VARCHAR(50) NULL UNIQUE , manager_id INTEGER NULL PRIMARY KEY AUTO_INCREMENT, FOREIGN KEY (manager_id) REFERENCES Employee(employee_id) );
CREATE TABLE Department (department_id INTEGER PRIMARY KEY AUTO_INCREMENT ,name VARCHAR(50) UNIQUE NULL , FOREIGN KEY (department_id) REFERENCES Managers(manager_id));

Employee:

@Entity
@Table (name = "employee")
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee{

public Employee(int id, String name, double salary, String specialization) {
    this.employee_id = id;
    this.name = name;
    this.salary = salary;
    this.specialization = specialization;
}

@Override
public String toString() {
    return "Employee{" +
            "id=" + employee_id +
            ", name='" + name + '\'' +
            ", salary=" + salary +
            ", deg='" + specialization + '\'' +
            '}';
}

public int getId() {
    return employee_id;
}

public void setId(int id) {
    this.employee_id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public double getSalary() {
    return salary;
}

public void setSalary(double salary) {
    this.salary = salary;
}

public String getSpecialization() {
    return specialization;
}

public void setSpecialization(String specialization) {
    this.specialization = specialization;
}

@Id
@Column(name = "employee_id")
private int employee_id;

@Column(name = "name")
private String name;
@Column(name = "salary")
private double salary;
@Column (name = "specialization")
private String specialization;

public Employee(){}
}

Department:

@Table(name = "department")
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Department extends Managers{

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public Department(String name) {
    this.name = name;
}

public Managers getManager() {
    return manager;
}

public void setManager(Managers manager) {
    this.manager = manager;
}

@OneToOne
@JoinColumn(name = "department_id" , referencedColumnName = "manager_id", insertable = false, updatable = false)
private Managers manager;

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

public int getDepartment_id() {
    return department_id;
}

public void setDepartment_id(int department_id) {
    this.department_id = department_id;
}

@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "department_id")
private int department_id;

public Department(){}

}

Managers:

@Table(name = "managers")
@Entity
public class Managers extends Employee{

@OneToOne
@JoinColumn(name = "manager_id", referencedColumnName = "employee_id" , insertable = false, updatable = false)
private Employee employee;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getLastname() {
    return lastname;
}

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

public Managers(String name, String lastname) {
    this.name = name;
    this.lastname = lastname;
}

public Managers(){}

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

public int getManager_id() {
    return manager_id;
}

public void setManager_id(int manager_id) {
    this.manager_id = manager_id;
}

@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "manager_id")
private int manager_id;

}

Persistence.xml:

   <?xml version="1.0" encoding="UTF-8"?>
   <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

<persistence-unit name="EmployeesTesting" transaction-type="RESOURCE_LOCAL">

    <provider>org.hibernate.ejb.HibernatePersistence</provider>

    <class>employee.Employee</class>
    <class>department.Department</class>
    <class>managers.Managers</class>

    <properties>
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/employees"/>
        <property name="javax.persistence.jdbc.user" value="root"/>
        <property name="javax.persistence.jdbc.password" value="****"/>
        <property name="javax.persistence.jdbc.Driver" value="com.mysql.jdbc.Driver"/>
    </properties>

</persistence-unit>

Main:

public static void main(String[] args) {

    System.out.println("In the main");
    EntityManagerFactory emfactory =   Persistence.createEntityManagerFactory("EmployeesTesting");
    EntityManager entityManager = emfactory.createEntityManager();

    Employee employee = new Employee(1000,"Maks",3500,"Programmer");
    Managers manager = new Managers("maks","Burkov");
    Department department = new Department("Programmers");

     if(entityManager.contains(employee)){
        System.out.println("In the contains , the object has persistence state! ");
        entityManager.getTransaction().begin();
        entityManager.persist(employee);
        entityManager.persist(manager);
        entityManager.persist(department);
        entityManager.getTransaction().commit();
        entityManager.close();
        emfactory.close();
        System.out.println("Data Inserted!");
    }

    else if (!(entityManager.contains(employee))){
        System.out.println("In the not contains, the object is detached! ");
        entityManager.getTransaction().begin();
        entityManager.merge(employee);
        entityManager.merge(manager);
        entityManager.merge(department);
        entityManager.getTransaction().commit();
        entityManager.close();
        emfactory.close();
        System.out.println("Data Inserted!");
    }

    System.out.println("Get out from main");
  }
}

Updated

I have done some tests based on your configuration and this is what you need to do in order make it happen:

Step One

  • Remove the @Inheritance(strategy = InheritanceType.JOINED) annotation from the entity definitions.
  • Remove the extends from Managers and Departments

Step Two

The @OneToOne mappings should be as follows

Employee:

@Entity
public class Employee {

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

    @OneToOne(mappedBy = "employee")
    private Manager manager;

Manager:

@Entity

public class Manager {

    @Id
    @Column(name = "manager_id")
    private Integer managerId;

    @MapsId
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "manager_id", referencedColumnName = "employee_id")
    private Employee employee;

Department:

@Entity
public class Department {

    @Id
    @Column(name = "department_id")
    private Integer departmentId;

    @MapsId
    @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name = "department_id", referencedColumnName = "manager_id")
    private Manager manager;

Dont forget about getters and setters..

Step Three

In order to persist all the entities properly, so that they all have one shared id, you have to save only the Department .. It looks like this:

        Employee emp = new Employee();
        emp.setEmployeeId(1);
        emp.setName("employee");

        Manager manager = new Manager();
        manager.setEmployee(emp);
        manager.setName("manager");

        Department department = new Department();
        department.setName("department");
        department.setManager(manager);

        em.persist(department);

After the transaction is commited all three entities will have their primary keys set to 1 .

The answer to my question was:

1.Adding the property to persistence.xml! To allow for the provider create the tables!

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

2.Adding the Cascade type for successful persistence!

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

public Employee(int id, String name, String lastname, double salary, String spec) {
    this.id = id;
    this.name = name;
    this.salary = salary;
    this.specialization = spec;
    this.lastname = lastname;
}

public int getId() {
    return id;
}

public String getName() {
    return name;
}

public double getSalary() {
    return salary;
}

public void setId(int id) {
    this.id = id;
}

public void setName(String name) {
    this.name = name;
}

public void setSalary(double salary) {
    this.salary = salary;
}

@Override
public String toString() {
    return "Employee{" +
            "id=" + id +
            ", name='" + name + '\'' +
            ", salary=" + salary +
            ", deg='" + specialization + '\'' +
            '}';
}

public String getLastname() {
    return lastname;
}

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

@Id
@Column(name = "id")
private int id;

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

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

@Column(name = "salary")
private double salary;

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

public Managers getManagers() {
    return manager;
}

public void setManagers(Managers manager) {
    this.manager = manager;
}

@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "manager_id")
private Managers manager;

public Employee(){}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM