2013-05-12 57 views
31

我正在使用本教程學習Spring,Hibernate,Maven:Chad Lung: A project using Netbeans 7, JUnit, Maven, HSQLDB, Spring and Hibernate。它工作正常,但我需要建立一對多的關係(一名員工有很多任務)。我已經嘗試了許多例子,但仍然不能得到的想法如何使我的代碼工作:如何使用Hibernate批註@ManyToOne和@OneToMany進行關聯

Employee.java:

package com.giantflyingsaucer.simplespringhibernate.entity; 

import javax.persistence.*; 
import java.io.Serializable; 
import java.util.List; 

@Entity 
@Table(name = "Employees") 
public class Employee implements Serializable { 

    private Integer employeeId; 
    private List<Task> tasks; 

    @Id 
    @Column(name = "idEmployees", nullable=false) 
    public Integer getEmployeeId() { 
     return this.employeeId; 
    } 

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

    @OneToMany(fetch = FetchType.LAZY) 
    @JoinColumn(name="idEmployees") 
    public List<Task> getTasks() { 
     return tasks; 
    } 
} 

Task.java:

package com.giantflyingsaucer.simplespringhibernate.entity; 

import javax.persistence.*; 
import java.io.Serializable; 

@Entity 
@Table(name = "Tasks") 
public class Task implements Serializable { 

    private Integer taskId; 
    private Employee employee; 


    @Id 
    @Column(name = "idTasks", nullable=false) 
    public Integer getTaskId() { 
     return this.taskId; 
    } 

    public void setTaskId(Integer taskId) { 
     this.taskId = taskId; 
    } 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "TasksIdEmployees") 
    public Employee getEmployee() {return employee;} 

} 

db-config.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd 
"> 
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
    destroy-method="close"> 

    <property name="driverClass"> 
     <value>${jdbc.driver.className}</value> 
    </property> 
    <property name="jdbcUrl"> 
     <value>${jdbc.url}</value> 
    </property> 
    <property name="user"> 
     <value>${jdbc.username}</value> 
    </property> 
    <property name="password"> 
     <value>${jdbc.password}</value> 
    </property> 
</bean> 
<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource"> 
     <ref bean="dataSource" /> 
    </property> 
    <property name="packagesToScan" value="com.giantflyingsaucer.simplespringhibernate.entity" /> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">${jdbc.hibernate.dialect}</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
      <prop key="hibernate.show_sql">false</prop> 
     </props> 
    </property> 
</bean> 
<bean id="transactionManager" 
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory"> 
     <ref bean="sessionFactory" /> 
    </property> 
</bean> 
<tx:annotation-driven /> 

MySQL表:

CREATE TABLE employees (
`idEmployees` int(11) NOT NULL, 
PRIMARY KEY (`idEmployees`) 
); 

CREATE TABLE tasks (
`idTasks` int(11) NOT NULL, 
`TasksIdEmployees` int(11) DEFAULT NULL, 
PRIMARY KEY (`idTasks`), 
KEY `FkTasksEmployees_idx` (`TasksIdEmployees`), 
CONSTRAINT `FkTasksEmployees` FOREIGN KEY (`TasksIdEmployees`) REFERENCES `employees` (`idEmployees`) ON DELETE NO ACTION ON UPDATE NO ACTION 
); 

非常感謝!

我找到了答案通過在NetBeans autogenerating映射文件和POJO:

// Employee.java: 
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "employees") 
    public List<Task> getTasks() { 
     return this.tasks; 
    } 

    public void setTasks(List<Task> tasks) { 
     this.tasks = tasks; 
    } 

// Task.java: 
@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "TasksIdEmployees") 
public Employee getEmployees() { 
    return this.employee; 
} 

public void setEmployees(Employee employee) { 
    this.employee = employee; 
} 

回答

56

錯誤之處在於以下幾點:

@OneToMany(fetch = FetchType.LAZY) 
@JoinColumn(name="idEmployees") 
public List<Task> getTasks() { 
    return tasks; 
} 

而且它是錯的,原因有二。

  1. @JoinColumn(name="idEmployees")意味着:這個一對多是使用命名idEmployees連接列(即外鍵)映射。但連接列未命名爲idEmployees。 idEmployees是Employee表的主鍵。連接列名稱是TasksIdEmployees。使用正確的名稱可以使映射正確處理單向OneToMany關聯。但協會是雙向的,這導致第二個原因...

  2. 在雙向關聯中,沒有必要(也是一個錯誤)重複關聯兩邊的映射信息。一方(多方)必須是該協會的所有者並定義該映射。另一方面必須簡單地說:反過來看另一方如何映射這個關聯。這樣做是使用的mappedBy屬性,它告訴Hibernate的另一邊是關聯的所有者字段或屬性的名稱:

    @OneToMany(mappedBy = "employee") 
    public List<Task> getTasks() { 
        return tasks; 
    } 
    

注意懶惰是一對多關聯的默認,所以沒有必要指定它。

+1

感謝您真正的好解釋! – Karloss 2013-05-12 22:24:25

+0

你能幫忙在http://stackoverflow.com/questions/18895585/hibernate-version-annotation-and-object-references-an-unsaved-transient-instanc – 2013-09-23 11:56:20

相關問題