Newsgroup: it.comp.java
Titolo: Hibernate: problemi con equals e tipo classe

Mi trovo in un'altra situzione scomoda con hibernate (che a quanto pare
non e' progettato cosi' bene per le interfacce e/o il polimorfismo).
La situazione e' quella descritta nel "Proxy Pitfall 2: instanceOf", qui
http://blog.xebia.com/2008/03/08/advanced-hibernate-proxy-pitfalls/
In pratica, se ho una gerarchia con MiaInterfaccia implementata da
MiaImplementazione, se ho un campo dichiarato "MiaInterfaccia pippo", che
e' in concreto un MiaImplementazione, quando Hibernate lo salva scrive
nel db la classe corretta, MiaImplementazione
Poi, però, se c'e' il lazy attivo, quando l'oggetto viene ricaricato,
pippo non e' del tipo concreto MiaImplementazione, ma di un sottotipo di
MiaInterfaccia, pero' "pari" o "vicino" (sibling in inglese) di
MiaImplementazione! Per via dell'uso dei proxy
E così per fare il test nell'equals di MiaImplementazione e' un casino,
perche' non posso usare né l'uguaglianza di getClass, ma neanche
instanceof, perché l'oggetto caricato non sarà instanceof
MiaImplementazione, ma instanceof MiaInterfaccia! 
Il bello, però, è che Hibernate.getClass dà come risultato
"MiaImplementazione", ma mica è vero, perché poi faccio un cast a
MiaImplementazione e da ClassCastException!
Morale, o si mette lazy a false, ma poi si carica tutto il mondo da db, 
oppure si fanno magheggi nel codice, oppure si cercano di evitare
situazioni polimorfiche come quella indicata, ma mi sembra davvero
assurdo che esista un problema così. Eppure, se anche altri lo indicano,
direi che avevo capito bene.
-- 
Herbie

 direi che avevo capito bene.
scusa, ma mi spieghi per quale ragione un pojo dovrebbe implementare una 
interfaccia? polimorfismo sulle entity del database? mah...
ciò premesso: tutto ciò ha una sua logica, se tu hai una classe che 
implementa un interfaccia significa hai deciso che il mondo esterno la 
deve vedere per quello che espone l'interfaccia medesima. altrimenti che 
senso ha? in teoria te ne dovresti fregare quale sia l'implementazione e 
che sia un proxy o meno. se invece non è così vuol dire che qualcosa non 
quadra nel tuo ragionamento.

 
http://blog.xebia.com/2008/03/08/advanced-hibernate-proxy-pitfalls/
Da quanto ho capito il problema si risolve facilmente, utilizzando il 
metodo isAssignableFrom() di java.lang.Class
Nel tuo caso:
MiaInterfaccia.class.isAssignableFrom(pippo.getClass())
pippo è un proxy fornito da Hibernate, e ovviamente bisogna essere 
sicuri che non sia null :)
-- 
Dimitri De Franciscis
Phone:  
(+39) 3401570778
Website: 
http://www.megadix.it/

 quadra nel tuo ragionamento.
Concordo. JPA espone all'applicazione delle ENTITA' che vogliono essere le
ENTITA' di un modello dati.
Nel momento che poliformizziamo le entita', l'applicazione non vede piu' il
modello dati mappato da JPA, ma vede un polimorph del modello dati , il che
mi suona come una quinta dimensione.
Al di la di ogni dibattito informatico ( o filosofico ? ) avremo comunque la
certezza di degradare notevolmente la leggibilita' del programma, il che va
evitato.
ciao Nicola
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 quadra nel tuo ragionamento.
non ho capito bene, ma spero che l'esempio postato possa spiegare in
dettaglio ciò che intendevo
-- 
Herbie

 mi suona come una quinta dimensione.
Non ho capito che intendevi dire. 
Vedi comunque l'esempio che ho postato poco fa, non è così strano.
-- 
Herbie

 wrote:
si parlava di come implementare equals quando si usa Hibernate, nel caso
di uso di polimorfismo, quando capita che i proxy non sono sottoclassi
della classe il cui equals viene richiamato, ma loro pari (sibling)
Grazie a dio qualcuno ha scritto un articolo di blog con la soluzione,
che alla fine ho trovato. Si fa così, quando si confronta la classe:
MySubClass.equals(Object obj):
.....
	MySubClass other;
	if (obj instanceof HibernateProxy) {
	//			code from
	//			
http://blog.jeremymartin.name/2008/02/java-reflection-hibernate-proxy-objects.html
	 			other = (MySubClass)
				((HibernateProxy)obj).getHibernateLazyInitializer().getImplementation();
	} else {
		other = (MySubClass) obj;
	}
in pratica si accede alla vera istanza dietro il proxy, e l'istanza
viene anche inizializzata, se necessario. 
Non mi pare si pongano problemi di detach, come l'autore prospettava, ho
fatto alcuni esperimenti che spero siano corretti
-- 
Herbie