如何在 Spring 中连接 @ManyToMany 关系

Posted

技术标签:

【中文标题】如何在 Spring 中连接 @ManyToMany 关系【英文标题】:How to connect @ManyToMany relationships in Spring 【发布时间】:2017-04-28 14:41:59 【问题描述】:

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

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

【问题讨论】:

在 JPA 中,我总是将多对多分解为一对多和多对一,它可以让您更好地控制级联,并且在以下情况下更容易移动关系映射表是显式的。 【参考方案1】:

在我看来:

    班次是一个独立的实体。它不依赖于任何员工。 所以Shift 不能有对Employee 的引用。

    另一方面,一名员工依赖多个班次,因此Employee 必须有unidirectional @OneToMany association 和Shift

    @OneToMany
    private List<Shift> shifts;
    并且不要在这里使用级联,因为EmployeeShift 是独立的实体。

更新

要“为员工添加班次”,我们可以使用例如 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);

【讨论】:

感谢您的建议,真的很有帮助!但是,我仍然不确定如何在我的 DatabaseLoader 类中为员工添加班次...例如:如何将星期五早上添加到 Adam Smith '我如何将星期五早上添加到亚当斯密?' - 例如Employee setter - 查看我更新的答案。【参考方案2】:

您似乎在后台使用 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 将在两个实体上执行插入操作。

【讨论】:

您好,感谢您的回复!但是,当我尝试实现您的方法时,出现以下错误: Unable to build Hibernate SessionFactory: Could not determine type for: java.util.Set, at table: shift, for columns: [org.hibernate.mapping.Column (employee)] ------------------ 我还更新了我上面的课程,这样你就可以确切地看到我所做的更改

以上是关于如何在 Spring 中连接 @ManyToMany 关系的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring 中连接相互依赖的 bean?

如何在 Spring/Tomcat 中完全禁用 JDBC 连接池?

如何在 Spring Data JPA 中更改数据库连接?

如何在spring boot中配置mybatis db连接?

如何在 YML 文件 spring boot 中配置 SSL mongodb 连接?

如何在 Spring Boot 中模拟数据库连接以进行测试?