¿Cómo hacer una relación de muchos a muchos en el ROO de primavera, con atributos dentro de la relación? -- many-to-many campo con relationship campo con spring-roo camp Relacionados El problema

How to do a many-to-many relationship in spring Roo, with attributes within de relationship?


3
vote

problema

Español

He estado investigando sobre este tema y no he encontrado alguna respuesta todavía. Estoy usando ROO de primavera y me gustaría saber si hay una forma en que puedo establecer una relación de muchos a muchos con atributos dentro de esta relación. Por ejemplo, tengo dos tablas de empleados y empleados, los empleados pueden reservar muchos equipos, y el equipo podría ser reservado por muchos empleados, sin embargo, quiero almacenar la fecha en que se realizó esta reserva.

Si alguien puede ayudar, lo apreciaría. ¡Gracias de antemano!

Original en ingles

i have been researching on this topic and havent found any answers yet. Im using spring roo and i would like to know if theres a way I can establish a many-to-many relationship with attributes within this relationship. For example i have two tables Employee and MedicalEquipment, Employees can reserve many equipments, and equipment could be reserved by many employee, however i want to store the date this reserve took place.

If some one can help i would appreciate it. Thanks in advance!

        

Lista de respuestas

9
 
vote
vote
La mejor respuesta
 
  • Para lograr una relación de muchos a muchos con atributos, necesita una tabla de unión que contenga las columnas adicionales. Es decir, además de los empleados y los equipos médicos, necesitará un tercer empleo de empleo.

  • Con respecto a JPA, tiene dos opciones:

    1. asignando la tabla de uniones a una entidad intermedia
    2. Mapeo de la tabla de uniones a una colección de componentes

El primero es más complicado, pero le permitió tener una navegación bidireccional (porque es una entidad y, por lo tanto, puede tener referencias compartidas), este último es más sencillo tanto en la construcción como en ello, pero no puedes usarlo. Para navegar entre entidades (sin embargo, puede escribir una consulta para recuperar los objetos que necesita)

  • Roo es un generador de código, pero carece de todas las opciones que ofrece JPA, por lo que debe editar las clases de Java y las clases de prueba. El edificio de la vista también tiene algunas limitaciones, por lo que también tendrá que editarlo.

En mi caso, necesitaba crear una entidad intermedia porque la tabla pertenece a una base de datos heredada que ya existía.

Hice algo así:

  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   

Además, debe garantizar la integridad referencial mediante la gestión de las colecciones en ambos lados de la asociación utilizando el constructor. Así que necesita editar la clase de tal manera:

  @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); } ...  }   

Intenté darte un ejemplo de una configuración de RoO.

Puede encontrar una mejor explicación de las cosas de JPA en el libro de Manning "Java Persistence con Hibernate", Capítulo 7.2.3.

Nota: Si usa Roo 1.2.1, la consulta de conteo generará SQL con "CUENTA (ID1, ID2)", que no es compatible con todas las bases de datos, incluida la HSQLDB. Puede personalizarlo así:

...

  -@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();         }     }   
 
  • In order to achieve a many-to-many relationship with attributes, you need a join table which contains the additional columns. That is, besides Employee and MedicalEquipment, you will need a third EmployeeMedicalEquipment.

  • Regarding JPA you have two options:

    1. Mapping the join table to an intermediate entity
    2. Mapping the join table to a collection of components

The former is more complicated, but it allowed you to have bidirectional navigation (because it's an entity and hence, can have shared references), the latter is simpler in both building it and using it, but you can't use it to navigate between entities (however, you can write a query to retrieve the objects you need)

  • Roo is a code generator, but it lacks of all the options that JPA offers, so you have to edit the Java classes, and the test classes. The building of the view has some limitations too, so you will need to edit it as well.

In my case, I needed to create an intermediary entity because the table belongs to a legacy database that already existed.

I did something like this:

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: youxc2xb4ll 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 

Furthermore, you need to guarantees referential integrity by managing collections on either side of the association using the constructor. So you need to edit the class in such way:

@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); } ...  } 

I tried to give you an example of a Roo configuration.

You can find a better explanation of the JPA stuff in the book from Manning "Java Persistence with Hibernate", chapter 7.2.3.

Note: if you use roo 1.2.1, the count query will generate SQL with "count(id1, id2)", which is not supported by all databases, including HSQLDB. You can customize it like this:

...

-@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();         }     } 
 
 
 
 
0
 
vote

¿Por qué no puedes tener una entidad separada para denotar su relación?

Solo introduzca una nueva entidad llamada MedicalEquipmentReservation que contendría todos los atributos de la reserva junto con las relaciones entre el empleado y las entidades de los equipos médicos.

ver el siguiente ejemplo.

   var tablearray = NSMutableArray() func getAssetThumbnail(asset: PHAsset) -> UIImage {     let manager = PHImageManager.default()     let option = PHImageRequestOptions()     var thumbnail = UIImage()     option.isSynchronous = true     manager.requestImage(for: asset, targetSize: CGSize(width: 100, height: 100), contentMode: .aspectFit, options: option, resultHandler: {(result, info)->Void in         thumbnail = result!     })     return thumbnail }  override func viewDidLoad() {     super.viewDidLoad()     // Do any additional setup after loading the view, typically from a nib.     //print(UnladenSwallow.unknown)      let fetchOptions = PHFetchOptions()      let smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .any, options: fetchOptions)      let topLevelfetchOptions = PHFetchOptions()      let topLevelUserCollections = PHCollectionList.fetchTopLevelUserCollections(with: topLevelfetchOptions)      let allAlbums = [topLevelUserCollections, smartAlbums]       var name = ""      smartAlbums.enumerateObjects({         if let collection = $0.0 as? PHAssetCollection{              name = collection.localizedTitle!              let image_arry = NSMutableArray()             let result = PHAsset.fetchAssets(in: collection, options: nil)             result.enumerateObjects({ (object, index, stop) -> Void in                 let asset = object                  image_arry.add(self.getAssetThumbnail(asset: asset))             })             let newAlbum = AlbumModel(name: name, count: collection.estimatedAssetCount, asset:image_arry)             self.tablearray.add(newAlbum)         }     })      topLevelUserCollections.enumerateObjects({         if let collection = $0.0 as? PHAssetCollection{              name = collection.localizedTitle!              let image_arry = NSMutableArray()             let result = PHAsset.fetchAssets(in: collection, options: nil)             result.enumerateObjects({ (object, index, stop) -> Void in                 let asset = object                 image_arry.add(self.getAssetThumbnail(asset: asset))             })             let newAlbum = AlbumModel(name: name, count: collection.estimatedAssetCount, asset:image_arry)             self.tablearray.add(newAlbum)         }     })      print(self.tablearray)  }   override func didReceiveMemoryWarning() {     super.didReceiveMemoryWarning()     // Dispose of any resources that can be recreated. } 0  

¡Saludos y todo lo mejor con la primavera!

 

Why can't you have a separate entity to denote your relationship?

Just introduce a new entity called a MedicalEquipmentReservation which would contain all the attributes of the reservation along with the relationships between the Employee and the Medical Equipment entities.

See the following example.

class MedicalEquipmentReservation{       //attributes       Date reservationStartDate;         Date reservationEndDate;       //relationships     Employee employee;      Set<Equipment> equipments; //assuming more than one equipment can be borrowed at one reservation } 

Cheers and all the best with Spring Roo!

 
 

Relacionados problema

1  Cómo llamar a Cargador de datos personalizado en Spring Application Start  ( How to call custom data loader on spring application start ) 
Estoy tratando de cargar algunos datos a mi DB en la aplicación START. Tengo un frijol definido para este propósito applicationcontext.xml <bean class="c...

2  Cambie la página de inicio predeterminada para la aplicación generada por Roo utilizando SpringMVC  ( Change default homepage for roo generated app using springmvc ) 
De forma predeterminada cuando la aplicación web se inicia, comienza con la página de inicio generada por Roo con el nombre de la vista como "índice" Supong...

1  ROO de primavera - actualizar una entidad desplegada  ( Spring roo update a deployed entity ) 
Supongamos que usar ROO de primavera, he creado una aplicación web con una entidad "Usuario" que almacena los datos de usuario. Tiene dos campos de cadena pri...

0  Primavera Roo y Oracle JDBC Dependency  ( Spring roo and oracle jdbc dependency ) 
Estoy usando Roo en un proyecto y cuando configuré JPA con proveedor de hibernación y Oracle como base de datos, la siguiente dependencia se inserta automátic...

4  ROO de primavera: el controlador JDBC no está disponible para 'org.h2.driver'  ( Spring roo jdbc driver not available for org h2 driver ) 
Estoy ejecutando Eclipse Indigo en Ubuntu Linux, Herramientas de primavera 2.7.1, ROO de primavera 1.1.5. Estoy leyendo Comenzando con Roo y cuando intento ...

0  El código de prueba generado de Roo no compila para la variable INT @ID  ( Roo generated test code does not compile for int id variable ) 
He creado un proyecto de primavera 1.2.5 muy simple con una clase de clase de entidad que tiene algunas variables de cadena. Añadido un @Id @GeneratedVal...

1  Actualizar / regenerar Pom.xml en Roo  ( Update regenerate pom xml in roo ) 
Tengo un proyecto que se hizo con la primavera Roo 1.0 que ahora quiero continuar usando ROO de primavera 1.1.4 con. Mucho ha cambiado desde entonces, así que...

3  Striping de cebra falla en primavera roo  ( Zebra striping fails in spring roo ) 
¿Por qué las rayas de cebra en la primavera roo trabajan en Firefox, Chrome y Opera, pero falla en Internet Explorer 9? Tome cualquiera de los ejemplos. Uti...

0  QUERYDSLRepositorySupport () implícito Súper ConstructorSupport () no está definido para el constructor predeterminado. Debe definir un constructor explícito  ( Implicit super constructor querydslrepositorysupport is undefined for default ) 
Yo uso Spring Roo + data de primavera + querydsl y tengo las siguientes clases / interfaces: public interface FamilyAdvertisementRepositoryCustom { }...

0  Objeto de detalle de ROO de primavera  ( Spring roo detail object ) 
Estoy usando primavera roo v2.0. Creé una aplicación simple con dos entidades: biblioteca y libro. Una biblioteca puede tener más libros, así que creé un rell...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos