2013-05-12 6 views
31

Tôi đang học Spring, Hibernate, Maven bằng cách sử dụng hướng dẫn này: Chad Lung: A project using Netbeans 7, JUnit, Maven, HSQLDB, Spring and Hibernate. Nó hoạt động ok nhưng tôi cần phải thực hiện mối quan hệ một-nhiều (một nhân viên có nhiều nhiệm vụ). Tôi đã cố gắng rất nhiều ví dụ nhưng vẫn không thể có được ý tưởng làm thế nào để làm cho công việc của tôi mã:Cách sử dụng chú thích Hibernate @ManyToOne và @OneToMany cho các liên kết

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

bảng 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 
); 

Cảm ơn rất nhiều!

Tôi tìm thấy một câu trả lời bằng autogenerating file Mapping và POJO trong NetBeans:

// 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; 
} 

Trả lời

56

Có chuyện gì vậy là như sau:

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

Và đó là sai vì hai lý do.

  1. @JoinColumn(name="idEmployees") có nghĩa là: OneToMany này được ánh xạ sử dụng một cột tham gia (ví dụ: một khoá ngoại) đặt tên idEmployees. Nhưng cột nối không được đặt tên là idEmployees. idEmployees là khóa chính của bảng Employee. Tên cột tham gia là TasksIdEmployees. Đặt đúng tên sẽ làm cho ánh xạ chính xác cho một hiệp hội OneToMany một chiều. Nhưng hiệp hội là hai chiều, dẫn đến lý do thứ hai ...

  2. Trong một liên kết hai chiều, không cần (và đó là lỗi) để lặp lại thông tin bản đồ trên cả hai mặt của hiệp hội. Một bên (nhiều bên) phải là chủ sở hữu của hiệp hội và xác định ánh xạ. Mặt khác phải là mặt nghịch đảo bằng cách đơn giản nói: đi xem ở phía bên kia cách liên kết này được ánh xạ. Này được thực hiện bằng cách sử dụng thuộc tính mappedBy, mà nói với Hibernate tên của trường hoặc tài sản ở phía bên kia là chủ sở hữu của hiệp hội:

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

Lưu ý rằng LAZY là mặc định cho các hiệp hội toMany, vì vậy không cần thiết phải chỉ định nó.

+1

Cảm ơn lời giải thích thực sự tốt! – Karloss

+0

bạn có thể vui lòng trợ giúp trong http://stackoverflow.com/questions/18895585/hibernate-version-annotation-and-object-references-an-unsaved-transient-instanc –