如何在 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;
-
并且不要在这里使用级联,因为
Employee
和Shift
是独立的实体。
更新
要“为员工添加班次”,我们可以使用例如 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/Tomcat 中完全禁用 JDBC 连接池?
如何在spring boot中配置mybatis db连接?