Domanda

Ho una classe Hibernate, che è essenzialmente un wrapper per i carichi di collezioni.

Quindi, la classe è (massicciamente semplificato / pseudo) qualcosa come:

@Entity  
public class MyClass {

  @OneToMany  
  Map1

  @OneToMany  
  Map2

  @OneToMany   
  Map3

  AddToMap1();  
  AddToMap2();  
  AddToMap3();  
  RemoveFromMap1();  
  RemoveFromMap2();  
  RemoveFromMap3();  
  DoWhateverWithMap1();  
  DoWhateverWithMap2();  
  DoWhateverWithMap3();  

}

ecc. Ciascuna di queste mappe, allora ha un paio di metodi ad esso associati (aggiungere / rimuovere / interrogare / etc).

Come si può immaginare, per il momento ho aggiunto il 10 ° di raccolta o giù di lì, la classe è sempre un po 'ridicolo in termini di dimensioni.

Quello che mi piacerebbe fare è qualcosa sulla falsariga di:

 
@Entity  
public class MyClass {

  ClassWrappingMap1;

  ClassWrappingMap2;

  ClassWrappingMap3;
}

Con tutti i vari metodi avvolto in tali classi:

public class ClassWrappingMap1 {

  @OneToMany
  Map

  AddToMap();  
  RemoveFromMap();  
  DoWhateverWithMap();  

}

ho pensato che forse avrei potuto usare @Embedded per questo, ma non mi sembra di essere in grado di farlo funzionare (Hibernate semplicemente non prova nemmeno a persistere la mappa all'interno della wrapperClass).

Qualcuno ha mai fatto qualcosa di simile prima? Eventuali suggerimenti?

Molte grazie,
Ned

È stato utile?

Soluzione

Hibernate manuale per le annotazioni Stati seguente :

  

Anche se non supportato dalla specifica EJB3, Hibernate annotazioni consente di utilizzare le annotazioni di associazione in un oggetto embeddable (ad esempio @ * @ * TOONE né pressi di molte). Per ignorare le colonne di associazione è possibile utilizzare @AssociationOverride.

Quindi il vostro approccio avvolgente dovrebbe funzionare.


Prima di tutto, si deve controllare tutti i file di log, ecc per eventuali errori correlati.

Si potrebbe provare qualcosa di simile:

  • Nella classe master (MyClass)
@Entity  
public class MyClass {

  @Embedded
  ClassWrappingMap1 map1;
}
  • E nella tua classe involucro
@Embeddable
public class ClassWrappingMap1 {

  @OneToMany
  Map map1;

}

Si noti che ClassWrappingMap1 utilizza annotazioni @Embeddable. Tuttavia, secondo i documenti non dovrebbe essere necessario l'annotazione @Embeddable, dovrebbe essere di default quando si usa l'annotazione @Embedded.

Assicurarsi che ogni classe ClassWrappingMap associa una colonna diversa nel database. Anche le classi ClassWrappingMap non dovrebbero avere una chiave primaria (@Id o colonne @EmbeddedId).

Altri suggerimenti

Anche se non so una strategia di default quando si utilizza una classe wrapper, è possibile utilizzare un Hibernate Interceptor per inizializzare wrapper di sovrascrivendo onLoad metodo. Qualcosa di simile

public class WrapperInterceptor extends EmptyInterceptor {

    private Session session;

    public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) {
        if (entity instanceof MyClass) {
             MyClass myClass = (MyClass) entity;

             Query query = session.createQuery(<QUERY_TO_RETRIEVE_WRAPPED_ENTITY_GOES_HERE>);

             WrappedEntity wrappedEntity = query.list().get(0);

             myClass.setWrapperClass(new WrapperClass(wrappedEntity));
        }
    }

    public void setSession(Session session) {
        this.session = session;
    }
}

Si prende cura di quanto segue:

  

Un client che utilizza questo intercettore deve impostare la proprietà Session

Quindi, il codice sia come questo

WrapperInterceptor interceptor = new WrapperInterceptor();

Session session = sessionFactory().openSession(interceptor);

Transaction tx = session.beginTransaction();

interceptor.setSession(session);

MyClass myClass = (MyClass) session.get(newItem, myClassId); // Triggers onLoad event

tx.commit();
session.close();

In alternativa, utilizzare Spring AOP per fare la stessa operazione. Vedere Domain Driven Design con la Primavera e Hibernate

Se si conosce un'altra strategia, condividerlo con noi.

saluti,

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top