Dan*_*iel 3 many-to-many relationship spring-roo
我一直在研究这个主题,还没有找到任何答案.我使用spring roo,我想知道是否有一种方式可以在这种关系中建立与属性的多对多关系.例如,我有两个表Employee和MedicalEquipment,员工可以预留许多设备,设备可以由许多员工预订,但是我想存储这个储备发生的日期.
如果有人可以帮助我会很感激.提前致谢!
为了实现与属性的多对多关系,您需要一个包含其他列的连接表.也就是说,除了Employee和MedicalEquipment之外,您还需要第三个EmployeeMedicalEquipment.
关于JPA,您有两种选择:
前者更复杂,但它允许你进行双向导航(因为它是一个实体,因此可以有共享引用),后者在构建和使用它时更简单,但是你不能用它来导航实体(但是,您可以编写查询来检索所需的对象)
就我而言,我需要创建一个中间实体,因为该表属于已经存在的遗留数据库.
我做了这样的事情:
entity --class ~.domain.Employee --table T_Employee [etc...]
field [etc...]
entity --class ~.domain.MedicalEquipment --table T_MedicalEquipment [etc...]
field [etc...]
entity --class ~.domain.EmployeeMedicalEquipment --table T_Employee_MedicalEquipment --identifierType ~.domain.EmployeeMedicalEquipmentId
//to store the date this reserve took place.
field date --fieldName reserveDate --column C_reserveDate [etc...]
//Bidirectional: you´ll need @JoinColumn insertable = false and updatable = false
field reference --fieldName employee --type ~.domain.Employee --cardinality MANY_TO_ONE
//Bidirectional: you'll need @JoinColumn insertable = false and updatable = false
field reference --fieldName medicalEquipment --type ~.MedicalEquipment --cardinality MANY_TO_ONE
//Join table's composite primary key
field string --fieldName employeeId --column employee_ID --class ~.domain.EmployeeMedicalEquipmentId [etc...]
field string --fieldName medicalEquipmentId --column medicalEquipment_ID --class ~.domain.EmployeeMedicalEquipmentId [etc...]
//Now, it's time to complete the relationship:
focus --class ~.domain.Employee
field set --type ~.domain.EmployeeMedicalEquipment --fieldName medicalEquipments --cardinality ONE_TO_MANY --mappedBy employee
focus --class ~.domain.MedicalEquipment
field set --type ~.domain.EmployeeMedicalEquipment --fieldName employees --cardinality ONE_TO_MANY --mappedBy medicalEquipment
Run Code Online (Sandbox Code Playgroud)
此外,您需要通过使用构造函数管理关联任一侧的集合来保证引用完整性.所以你需要以这样的方式编辑类:
@RooEntity(...
public class EmployeeMedicalEquipment {
@ManyToOne
@JoinColumn(name = "employeeId", referencedColumnName = "employeeId", insertable = false, updatable = false)
private Employee employee;
@ManyToOne
@JoinColumn(name="medicalEquipmentId", referencedColumnName="medicalEquipmentId", insertable=false, updatable=false)
private MedicalEquipment medicalEquipment;
/**
* No-arg constructor for JavaBean tools
*/
public EmployeeMedicalEquipment() {
}
/**
* Full constructor, the Employee and MedicalEquipment instances have to have an identifier value, they have to be in detached or persistent state.
* This constructor takes care of the bidirectional relationship by adding the new instance to the collections on either side of the
* many-to-many association (added to the collections)
*/
public EmployeeMedicalEquipment(Employee employee, MedicalEquipment medicalEquipment, Date reserveDate) {
this.setReserveDate (reserveDate);
this.employee = employee;
this.medicalEquipment = medicalEquipment;
this.setId(new EmployeeMedicalEquipmentId(employee.getId(), medicalEquipment.getId());
// If Employee or MedicalEquipment Guarantee referential integrity
employee.getMedicalEquipments().add(this);
medicalEquipment.getEmployees().add(this);
}
...
}
Run Code Online (Sandbox Code Playgroud)
我试着给你一个Roo配置的例子.
您可以在Manning"Java Persistence with Hibernate"一书中找到有关JPA内容的更好解释,第7.2.3节.
注意:如果使用roo 1.2.1,count查询将生成带有"count(id1,id2)"的SQL,所有数据库都不支持,包括HSQLDB.您可以像这样自定义它:
...
-@RooJpaActiveRecord(identifierType = EmployeeMedicalEquipmentId.class, table = "T_Employee_MedicalEquipment")
+@RooJpaActiveRecord(identifierType = EmployeeMedicalEquipmentId.class, table = "T_Employee_MedicalEquipment", countMethod="")
...
public class EmployeeMedicalEquipment {
...
// count method initially copied from ActiveRecord aspect
public static long countEmployeeMedicalEquipments() {
- return entityManager().createQuery("SELECT COUNT(o) FROM EmployeeMedicalEquipment o", Long.class).getSingleResult();
+ return entityManager().createQuery("SELECT COUNT(o.employee) FROM EmployeeMedicalEquipment o", Long.class).getSingleResult();
}
}
Run Code Online (Sandbox Code Playgroud)