2017-02-08 3 views
0

У меня есть такая проблема!Как устанавливаются отношения между таблицами в JPA?

я получил ошибку:

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

В чем проблема с моими полями? Чего не хватает?

Полный трассировки стека:

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 Таблица:

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

Сотрудник:

@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(){} 
} 

Факультет:

@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(){} 

} 

Менеджеры:

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

Главная:

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"); 
    } 
} 
+0

Я бы подумал, что маловероятно, что Департамент должен продлить Менеджер для начала. Менеджер ** является ** Работником. Менеджер/сотрудник ** имеет ** отдел. –

ответ

1

Обновлено

Я сделал некоторые тесты, основанные на вашей конфигурации, и это то, что вам нужно сделать для того, чтобы это произошло:

Шаг первый

  • Удалите @Inheritance(strategy = InheritanceType.JOINED) аннотацию из определений сущностей.
  • Удалите extends из Managers и Departments

Шаг Два

В @OneToOne отображения должен быть следующим

сотрудников:

@Entity 
public class Employee { 

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

    @OneToOne(mappedBy = "employee") 
    private 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; 

Факультет:

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

Не забудьте о добытчиками и сеттеров ..

Шаг третий

Для того, чтобы сохраняться все объекты должным образом, так что все они имеют один общий идентификатор, вы должны сохранить только Department .. Это выглядит следующим образом:

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

После совершения транзакции все три объекта будут иметь свои первичные ключи, установленные на 1.

+0

Я удалил extends с помощью стратегии Inheritance и добавил @Id! Теперь я получил эту ошибку: не могу добавить или обновить дочернюю строку: ограничение внешнего ключа не выполняется ('employees'''managers', CONSTRAINT' manager_ibfk_1' FOREIGN KEY ('manager_id') ССЫЛКИ' employee' ('employee_id')) –

+0

Я бы удалил эти атрибуты insertable = false из аннотаций @JoinColumn. Вы хотите вставить их наверняка .. вероятно, не обновлять, а вставлять yets –

+0

Хорошо, но я получаю то же исключение! –

0

Ответ на мой вопрос был:

1.Adding свойство persistence.xml! Чтобы провайдер мог создавать таблицы!

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

2.Добавление типа каскада для успешной настойчивости!

@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(){} 
} 
Смежные вопросы