2013-05-12 19 views
31

このチュートリアルを使用してSpring、Hibernate、Mavenを学習しています:Chad Lung: A project using Netbeans 7, JUnit, Maven, HSQLDB, Spring and Hibernate。それは正常に動作しますが、私は1対多の関係を作る必要があります(1人の従業員には多くのタスクがあります)。私は多くの例を試してみましたが、それでも私のコードを機能させるためにどのようにアイデアを得ることができません。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でのマッピングファイルと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; 
} 

そして、それは2つの理由のために間違っているのです。

  1. @JoinColumn(name="idEmployees")意味:このOneToManyはidEmployees名前結合列(すなわち、外部キー)を使用してマッピングされます。ただし、結合列の名前はidEmployeesではありません。 idEmployeesは、Employeeテーブルの主キーです。結合列名はTasksIdEmployeesです。正しい名前を付けることで、一方向のOneToManyの関連付けが正しいマッピングになります。しかし、アソシエーションは双方向であるため、2番目の理由があります。

  2. 双方向アソシエーションでは、アソシエーションの両側でマッピング情報を繰り返す必要はありません(バグです)。一方の側(多くの側)がアソシエーションの所有者であり、マッピングを定義していなければなりません。もう一方の側は、単純に言って逆の側でなければなりません。 、LAZYがtoManyアソシエーションのデフォルトであることを

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

注:これは組合の所有者である他の側にフィールドまたはプロパティの名前を休止伝えmappedBy属性を使用して行われますそれを指定する必要はありません。

+1

本当に良い説明をありがとう! – Karloss

+0

あなたはhttp://stackoverflow.com/questions/18895585/hibernate-version-annotation-and-object-references-an-unsaved-transient-instancで助けてもらえますか? –

関連する問題