Newsgroup: it.comp.java
Titolo: Hibernate: invocazione da sezioni static

Non mi ero reso conto che quando si chiama il classico
new Configuration().configure().buildSessionFactory();
per creare la session factory di Hibernate, lui va a guardarsi tutte le
classi coinvolte nel mapping, e con ciò intendo che il class loader va a
caricare tutte quelle classi. Appena caricate, viene eseguito il codice
static di inizializzazione, sia esso l'assegnazione di una variabile o
una sezione static {}. 
Risulta quindi impossibile inserire nel codice static una chiamata alla
sessione di Hibernate, perché cosa succede? Succede che il codice static
richiederà una sessione che non può crearsi, in quanto il HB vuole
leggere la classe, ma la classe, appena la si carica, vuole una session
che non è stata ancora creata.
Insomma, avevo:
public class AQFactory {
//    singleton instance
    private static AQFactory instance;
 
    static {
    	// TODO: rendere esterno?
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();
 
		long myId = 1; // only one instance
		AttributoQuotaFactory aqf = (AttributoQuotaFactory) session.get(AQFactory.class, myId);
 
		// if preexisting factory is found...
		if (aqf != null) {
			instance = aqf;
		} else {
			instance = new AttributoQuotaFactory();
			session.saveOrUpdate(instance);
		}
 
    }
...    
e se da un main di altra classe B eseguo
    Session session =   HibernateUtil.getSessionFactory().getCurrentSession();
    session.beginTransaction();
il codice static di A avrà null nella var session, perché B dice ad
Hibernate di inizializzare la session factory, lui fa partire il codice
static in HibernateUtil, e a sua volta carica B ed il class loader
lancia il codice statico di B, che però non trova una session factory
pronta, come, superficialmente, il codice potrebbe far pensare.
Quel codice in AQFactory mi serviva perché ho che AQFacroty è una
factory con un pool di oggetti, e volevo persistere questo pool. Nel
momento in cui ricreo l'istanza di A (che è un singleton), volevo vedere
se ricrearlo ex novo o ricaricarlo da db. Così, mi risulta impossibile
farlo a priori, e dovrò creare la factory e poi eventualmente caricarla
da db. Corretto?
Ma la domanda fondamentale che mi sono fatto è: è corretto persistere
una factory? O meglio, insomma, il suo pool di oggetti?
Io mi sono riposto di sì, perché se non lo salvo e ricarico, la factory
creerà poi nuovi oggetti, e a me serve che, data ad esempio una chiave
"PIPPO", mi venga restituito da quella factory sempre lo steso identico
oggetto.
Per completezza, questo era il resto del codice
-------
public class HibernateUtil {
	private static final SessionFactory sessionFactory;
    static {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            sessionFactory = new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
 
    }
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}
-- 
Herbie

 che non è stata ancora creata.
Confermo questo, ma mi rispondo da solo: ciò che volevo fare si può col
lazy loading, butto tutto il codice static dentro il getInstance.
 public static AttributoQuotaFactory getInstance() {
    	if (instance == null) {
			Session session = HibernateUtil.getSessionFactory().getCurrentSession();
			session.beginTransaction();
 
			long myId = 1; // only one instance
			AttributoQuotaFactory aqf = (AttributoQuotaFactory) session.get(AttributoQuotaFactory.class, myId);
 
			// if preexisting factory is found...
			if (aqf != null) {
				instance = aqf;
			} else {
				instance = new AttributoQuotaFactory();
				session.saveOrUpdate(instance);
			}
    	}
        return instance;
    }
-- 
Herbie