如何在Spring中连接@ManyToMany关系

时间:2017-04-28 14:41:59

标签: java spring jpa spring-data-jpa h2

我正在创建一个使用员工和班次之间多对多关系的应用程序。但是,我很难理解如何将员工分配/连接到班次。

@Data
@Entity
public class Employee {

private @Id @GeneratedValue long employeeID;
private String Name;

@OneToMany(cascade = CascadeType.ALL)
private Set<Shift> shifts;

private Employee() {
}

public Employee(long employeeID, String Name) {
    this.employeeID = employeeID;
    this.Name = Name;
}

public Employee(long employeeID, String Name, Set<Shift> shifts) {
    this.employeeID = employeeID;
    this.Name = Name;
    this.shifts = shifts;
}

public void setShift(Set<Shift> shifts) {
    this.shifts = (Set<Shift>) shifts;
}

}

@Data
@Entity
public class Shift {

private @Id @GeneratedValue long Id;
private String shifts;

private Set<Employee> employee;

private Shift() {
}

public Shift(String shifts) {
    this.shifts = shifts;
}

public Shift(String shiftPeriod,Set<Employee> employee ) {
    this.shifts = shifts;
    this.employee=employee;
}

public void setEmployee(Set<Employee> employee) {
    this.employee = employee;
}

}

@Component
public class DatabaseLoader implements CommandLineRunner {

private final EmployeeRepository repository;

@Autowired
public DatabaseLoader(EmployeeRepository repository) {
    this.repository = repository;
}

@Override
public void run(String... strings) throws Exception {
    Shift shift = new Shift("Friday Morning");
    Employee employee = new Employee(0001, "Adam Smith");

    employee.setShift(shift);
    this.repository.save(employee);
}

}

public interface ShiftRepository extends CrudRepository<Shift, Long> 

public interface EmployeeRepository extends CrudRepository<Employee, Long>

添加到员工中的实体和班次已保存,但有一种方法可以在DatabaseLoader类中为员工分配班次,因为我一直坚持寻找解决方案。

我知道我没有包含一个尝试连接员工和班次的方法,但我不知道如何解决这个问题。

提前致谢

**编辑:我现在遇到的新问题是,在尝试在春季部署时,我收到以下消息:

无法构建Hibernate SessionFactory:无法确定类型:java.util.Set,在表:shift,对于列:[org.hibernate.mapping.Column(employee)]

2 个答案:

答案 0 :(得分:0)

在我看来:

  1. 班次是一个独立的实体。它不依赖于任何员工。 因此Shift不得引用Employee

  2. 另一方面,员工依赖于多个班次,因此Employee必须unidirectional @OneToMany associationShift

  3.     @OneToMany
        private List<Shift> shifts;
    
    1. 此处不使用级联,因为EmployeeShift是独立的实体。
    2. <强>更新

      To&#34;向员工添加班次&#34;我们可以使用例如Employee setter:

      @Entity
      public class Employee {
          //...
          private String name;
          //...
          @OneToMany
          private List<Shift> shifts;
          //...
          public Employee(String name) {
              this.name = name;
          }
          //...
          public setShifts(Shift... shifts) {
              this.shifts = Arrays.asList(shifts);
          }
          //...
      }
      

      然后

      Shift monday = shiftRepository.save(new Shift("Monday"));
      Shift friday = shiftRepository.save(new Shift("Friday"));
      Employee adamSmith = new Employee("Adam Smith");
      adamSmith.setShifts(monday, friday);
      employeeRepository.save(adamSmith);
      

答案 1 :(得分:0)

您似乎正在使用Hibernate,那么您所要做的就是设置要正确保存的对象,如下所示:

@Component
public class DatabaseLoader implements CommandLineRunner {

private final EmployeeRepository repository;
private final ShiftRepository shiftRepository;

@Autowired
public DatabaseLoader(EmployeeRepository repository, ShiftRepository shiftRepository) {
    this.repository = repository;
    this.shiftRepository=shiftRepository;
}

@Override
public void run(String... strings) throws Exception {
    Shift shift = new Shift("Friday Morning");
    Employee employee = new Employee(0001, "Adam Smith");

    employee.setShift(shift)
    this.repository.save(employee);
}

唯一的区别是我连接在两个对象之间,然后我才尝试保存它们。值得一提的是,使用Cascade.All或Cascade.persiste非常重要,因为hibernate将在两个实体上执行插入操作。