Newsgroup: it.comp.java
Titolo: JBOSS ... lento!

Salve,
sto provando JBOSS 3.0 e, nonostante sia
concettualmente uno strumento fantastico,
le performance mi lasciano molto perplesso.
In particolare non capisco perche' in un
esempio utilizzando un solo (!) EJB EntityBean
di tipo Remoto e CMP (che dispone di due sole proprieta':
ID integer, INFO string) se vi faccio una query
di tipo "findAll()" e poi, su ogni stub ritornato,
chiamo il metodo "getInfo()" continuo a vedere
SELECT verso il DB. 
Mi sarei, insomma, aspettato di vedere, per 30
record, solo 30 "SELECT info FROM mytable WHERE ID=?"
al primo lancio del client, e non tutte le volte
che lancio il client (_senza_ aver effettuato il
restart di JBOSS).
Ed ancora: com'e' che per recuperare 300 "info" (da
altrettanti record/bean) impiega 5sec su un K900
con 512Mbyte di RAM (RedHat7.2+Jboss3.0+PostgresSQL7)?
Grazie per ogni suggerimento.
Saluti,
Roberto Colmegna

 restart di JBOSS).
Ciò è a discrezione del container e di come è configurato per cachare i dati
Ciao
Luigi

***  JBoss NON E' LENTO! ***
Anche io sto utilizzando JBoss 3.0.1.
Confermo quanto detto da Luigi Viggiano per quello che riguarda la 
lentezza d'acccesso a un Entity Bean remoto.
In questo modo Jboss deve forzatamente accedere al database ogni volta,
altrimenti in che CAVOLO DI MANIERA potrebbe assumere che i
i dati non sono stati cambiati (esternamente) nel database?
Quando gli chiedi dei dati, per lui non fa differenza se
glieli richiederai una seconda volta fra un millisecondo o fra una 
settimana... :-)
Non si dovrebbe esporre degli entity beans verso fuori,
benche' questo sia espressamente permesso dalla specifica EJB.
Meglio utilizzare un session bean remoto,
e degli entity beans locali.
Al client viene cosi' ritornata una collection
di VALUE OBJECTS, che sono degli oggetti serializzabili e quindi 
trasportabili, come diceva giustamente viggiano.
La lentezza NON sta nel findAll(), su questo non sono d'accordo.
findAll() di per se in Jboss e' performante
(a me ritorna un migliaio di records in circa 0.2 secondi).
Scusate se e' troppo... provare x credere. ;-)
Per non avere l'effetto "n+1" (n+1 accessi al database per n records)
ho dovuto osservare queste regole:
1. Utilizzare una session remota e chiamare l'app server una sola volta
    per tutti i dati che occorrono
    (oppure, se son troppi, una porzione del tutto)
    In questo modo tutti i records vengono
    chiesti al database in una SOLA TRANSAZIONE.
2. La session chiama findAll() e ottiene una Collection di
    referenze a Entities LOCALI.
3. La session fa un'ITERAZIONE attraverso la Collection ed estrae
    TUTTI i campi da OGNI entity bean.
    (Ora il database non viene interrogato ogni volta siccome siamo
     sempre all'interno DELLA STESSA TRANSAZIONE)
4. La session compone una LISTA, oppure un ARRAY, oppure una COLLECTION
    di oggetti di trasporto indipendenti dagli entity beans.
    Questa viene ritornata al client.
In questa maniera il client dispone di una COPIA dei dati,
e vengono evitati numerosi ROUND-TRIPS al server (e i rispettivi accessi 
al batabase).
Osservando gli accessi al database ho trovato 2 select al database,
indipendentemente dal numero di records ritornati.
L'algoritmo che implementa la CMP in Jboss e' pluggabile,
per ora fa una SELECT PK FROM... WHERE... per trovare tutte le PK del 
findAll(),
poi una select * con tantissime WHERE PK=1 AND PK=2 AND PK=33 AND PK=22 
AND PK=...
(Diventa una stringa SQL lunghissima...) :-)
Questo naturalmente funziona per tabelle con pochi dati...
Fino ad alcune migliaia a regola funzia.
Sono quasi certo che svilupperanno un'altro algoritmo
per la query dei dati, in maniera da poter interrogare, volendo,
anche una tabella ben indicizzata con un numeno enorme di records.
Hope this helps
Luigi Antognini

-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com
 - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----

 indipendentemente dal numero di records ritornati.
X curiosità: puoi indicarmi le classi?
Ciao
Jigi.

Hope this helps
YES, thansk!!!!  :)))
Bye
Roberto Colmegna

 quanto sopra, ma a me non lo evita comunque ... :(
Su questo non so esserti utile.
Luigi

 Gia' che ci sono ne approfitto (!): come posso risolvere? :) TIA!
HomeInterface ed HomeLocalInterface dovrebbero avere due JNDI
bindings differenti. In parole povere hanno due stringhe di lookup
diverse. Questo almeno ho sperimentato su Weblogic:
<weblogic-enterprise-bean>
    <ejb-name>TrxFactBean</ejb-name>
    <entity-descriptor>
[...]
    <jndi-name>TrxFact</jndi-name>
    <local-jndi-name>LocalTrxFact</local-jndi-name>
</weblogic-enterprise-bean>
Purtroppo non so come funziona JBoss ma potrebbe avere un
descrittore da qualche parte con un meccanismo analogo.
In secondo luogo per effettuare una lookup della LocalHomeInterface
di un entity penso che tu debba essere nella stessa JVM dell'entity
se no non c'è nessun meccanismo remoto (RMI è messo fuori gioco in
questo caso) che permetta alla tua chiamata di arrivare fino
all'entity. In altre parole, la lookup di una LocalInterface
dovrebbe avvenire da parte di un altro entity, session oppure classe
plain purchè sia in esecuzione nello stesso container. Non ricordo
bene, ma credo che weblogic esponesse le interfacce locali solo nel
JNDI tree ottenuto internamente al container (e non in quello
pubblicato sulla porta t3://somehost:7001).
Ciao
--
Renzo
Email: 
SASSAMIren...@tin.it
(Remove "SASSAMI" to reply)

Mi riferivo alla specifica EJB 2.0 (implementata in Jboss 3.0.x)
Probabilmente tu parli di EJB 1.1 (l'unica supportata in Jboss 2.x).
Personalmente ho lavorato soltanto con Jboss 3.0.x.
Credo ci sia una sostanziale differenza in come viene trattato un findAll()
in EJB 1.1 con entities remoti (anche se caricati in locale all'interno 
della session)
e in EJB 2.0 con entities locali.
Non vorrei metterci la mano sul fuoco,
ma presumo che findAll con CMP in LOCALE sia molto piu' efficente.
In questo caso non credo che venga popolata una collection di PK,
bensi' direttamente una collection di Local EJB References.
In questo modo il container puo' pololare piu' di un entity bean
alla volta...
Probabilmente legge il ResultSet della query e ne popola
diversi (read-ahead).
poi tu li leggi le entities con l'iteratore...
Man mano iteri, lui ripopola nuovi local entity beans,
(magari riciclandoli da un pool).
Per questo NON ha bisogno di un nuovo statement SQL,
ma continua la lettura del database dalla posizione attuale
del cursore (o ResultSet se preferisci in termini JDBC).
Facendo cosi' hai un solo statement SQL
per tutti gli oggetti del findAll.
Una parolina per il DAO.
Trovo peccato fare un SQL secco sul database,
se possibile lo eviterei.
Il bello di EJB 2.0 e' che puoi delegare il mapping con
il batabase al deployment (e rimane efficente lostesso).
Luigi



Si effettivamente utilizzerei gli entities in locale.
Per il lookup non puoi utilizare lo stesso metodo come
in remoto, devi fare una local-ejb-def nel deployment descriptor,
Si tratta di un naming NON GLOBALE,
ma riferito al bean al quale lo associ.
Un po' macchinoso, ma funzia.
se macini l'inglese leggiti "Enterprise JavaBeans, 3rd edition" di 
Monson-Haefel.
ISBN 0-596-00226-2
Ti spiega tutto a puntino, un bel librone.
da leggere a tempo perso, mi e' servito un casino :-)
In genere non credo che faccia senso rinunciare alle novita' della
specifica 2.0.
La grande differenza fra EJB 1.1 e 2.0 grosso modo e':
1) Introduzione di Entities e Sessions locali
    (chiamate direttamente con calls java e non via RMI(/IIOP) in rete,
     tutti i parametri sono passati BY REFERENCE).
2) CMP migliorata (e incompatibile sob...).
    i metodi findXXX possono essere implementati con un linguaggio
    di query indipendente dal database vendor, che si chiama EJB-QL.
3) Relazioni fra Entities (CMR)
    (Relazioni uni/bidirezionali 1-1, 1-n, n-n fra entities,
     con mappaggio nel batabase con FOREIGN keys oppure con una
     tabella di aggregazione)
     Le relazioni funzionano SOLTANTO con entities LOCALI
4) Possibilita' di NAVIGARE fra le relazioni nel codice
    Ad es. client().getBusinessAddress().getCompany().getCountry()
5) Possibilita' di QUERIES EJB-QL che comprendono anche le relazioni
    fra entities (anche se meno fressibile, un po' come
    delle JOINS in SQL).
6) Message Driven Beans ,per ricevere chiamate asincrone
    via JMS (Java Message Service)
La specifica 2.0 e' datata settembre 2001... ora c'e' gia' la 2.1 :-)
Dati i vantaggi, non esito ad utilizzarla appieno.
Luigi

