2009-04-29 9 views
0

J'ai une situation dans laquelle je travaille avec EJB3 et une base de données existante. J'ai une situation où il y a une relation many-to-many entre deux tables A et B, définies par une troisième table (link) L.EJB3 - Gestion des tables de liaison non standard

La complication est que la table de liaison a d'autres champs dans la table que la PK des tables A et B. Les colonnes sont des colonnes d'horodatage et d'utilisateur standard pour enregistrer qui a généré le lien. Ces deux colonnes supplémentaires m'empêchent de définir la relation many-many en utilisant une annotation de table de jointure, car elles ne sont pas nillables et doivent donc être remplies.

Est-ce que quelqu'un connaît un moyen de contourner cette limitation? Je pourrais définir des relations Un-à-plusieurs de la table de liens vers chacune des autres tables de la relation, mais ce n'est pas très élégant.

Merci,

Répondre

1

Oui, il est, mais vous devez le rendre élégant. La super-classe suivante peut être utilisée pour définir many-to-many arbitraire comme une entité:

@MappedSuperclass 
public abstract class ModelBaseRelationship { 

    @Embeddable 
    public static class Id implements Serializable { 

     public Long entityId1; 
     public Long entityId2; 

     @Column(name = "ENTITY1_ID") 
     public Long getEntityId1() { 
      return entityId1; 
     } 

     @Column(name = "ENTITY2_ID") 
     public Long getEntityId2() { 
      return entityId2; 
     } 

     public Id() { 
     } 

     public Id(Long entityId1, Long entityId2) { 
      this.entityId1 = entityId1; 
      this.entityId2 = entityId2; 
     } 

     @Override 
     public boolean equals(Object other) { 
      if (other == null) 
       return false; 
      if (this == other) 
       return true; 
      if (!(other instanceof Id)) 
       return false; 
      final Id that = (Id) other; 
      return new EqualsBuilder().append(this.entityId1, that.getEntityId1()).append(this.entityId1, that.getEntityId2()).isEquals(); 
     } 

     @Override 
     public int hashCode() { 
      return new HashCodeBuilder(11, 111).append(this.entityId1).append(this.entityId2).toHashCode(); 
     } 

     protected void setEntityId1(Long theEntityId1) { 
      entityId1 = theEntityId1; 
     } 

     protected void setEntityId2(Long theEntityId2) { 
      entityId2 = theEntityId2; 
     } 
    } 

    protected Id id = new Id(); 

    public ModelBaseRelationship() { 
     super(); 
    } 

    public ModelBaseRelationship(ModelBaseEntity entity1, ModelBaseEntity entity2) { 
     this(); 
     this.id.entityId1 = entity1.getId(); 
     this.id.entityId2 = entity2.getId(); 
     setVersion(0); 
    } 

    @EmbeddedId 
    public Id getId() { 
     return id; 
    } 

    protected void setId(Id theId) { 
     id = theId; 
    } 

} 

L'exemple de l'entité basée sur cette super classe (fragment):

@Entity(name = "myRealEntity") 
@Table(name = "REAL_TABLE_NAME", uniqueConstraints = { @UniqueConstraint(columnNames = { 
"FIRST_FK_ID", "SECOND_FK_ID" }) }) 
@AttributeOverrides({ 
@AttributeOverride(name = "entityId1", column = @Column(name = "FIRST_FK_ID")), 
@AttributeOverride(name = "entityId2", column = @Column(name = "SECOND_FK_ID"))  
}) 
public class ModelBaseRelationshipReferenceImpl extends ModelBaseRelationship { 

    private Entity1OfManyToManyRelationship entity1; 
    private Entity2OfManyToManyRelationship entity2; 
    ... 
    @ManyToOne 
    @JoinColumn(name = "FIRST_FK_ID", insertable = false, updatable = false) 
    public Entity1OfManyToManyRelationship getEntity1OfManyToManyRelationship() { 
    return entity1; 
    } 

    @ManyToOne 
    @JoinColumn(name = "SECOND_FK_ID", insertable = false, updatable = false) 
    public Entity2OfManyToManyRelationship getEntity2OfManyToManyRelationship() { 
    return entity2; 
    } 
... 
} 
+0

Salut Grigory, merci pour la réponse, mais je ne suis pas sûr de vous suivre correctement ici. Qu'est-ce que cela vous donne réellement? Pour le moment, cela fonctionne en utilisant les annotations @ManyToOne sur A et B, et OneToMany sur L - je préférerais me débarrasser du besoin de L (en tant qu'entité). Je ne suis pas vraiment sûr de ce que votre super-classe réalise ici. –

+0

il fait ce qui suit: il définit la table de liaison comme une entité complète avec la clé unique, structure de clé primaire de la table de liaison. Je vais modifier le dernier exemple pour ajouter des relations pour le rendre clair. – topchef

+0

La superclasse est vraiment une classe abstraite qui vous permet de réutiliser beaucoup de code dans le cas où vous avez plus d'un cas de table de liens en tant qu'entité ... Désolé de ne pas avoir clarifié cela plus tôt. Vous pouvez facilement le plier en classe d'entité unique si vous n'avez pas besoin d'être réutilisé. – topchef

Questions connexes