# struts Hibernate MySQL Select Statement



## paidopoieo (11. Apr 2006)

hi, 
habe eine mySQL Datenbank mit zwei Tabellen Protein und Peptide und moechte ein uebergreifendes select statement durchfuehren. 
habe folgende Methode: 


```
public Protein_Peptide[] getPeptideSeqAndProteinName() {
		/* will hold the entries we are going to return later */
		List proPep = new ArrayList();
		/* a Hibernate session */
		Session session = null;
		/* we always need a transaction */
		Transaction tx = null;

		/* get session of the current thread */
		session = HibernateSessionFactory.currentSession();

		tx = session.beginTransaction();
		List tmpProPep = session.createQuery(
		"select pept.peptide_seq, prot.name_of_protein from Peptide pept, Protein prot where pept.length_of_peptideseq = 4 and           prot.protein_id = pept.peptide_id").list();
		for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {
			proPep.add((Protein_Peptide) iter.next());
		}
		tx.commit();

		return (Protein_Peptide[]) proPep.toArray(new Protein_Peptide[0]);
	}
```

und bekomme folgende Fehlermeldung:

```
java.lang.ClassCastException: [Ljava.lang.Object;
```

in dieser Zeile

```
proPep.add((Protein_Peptide) iter.next());
```

verwende Struts und Hibernate, habe fuer jede Tabelle ein cfg.xml file.....und die entsprechende Klasse und ActionForm....
um ein uebergreifendes Select Statement zu machen, dachte ich mir ich mach eine neue klasse aus beiden zusammen (Protein_Peptide)
und dann klappt das....

sorry, vielleicht eine bloede frage aber ich bin ein anfaenger mit java...

mfg


----------



## Gumble (11. Apr 2006)

Die kriegst keine Objekte vom Typ 'Protein_Peptide' zurueck, sondern Tupel vom Typ 'Object[]' da du ja die Tabellen joinst.
looki: http://www.hibernate.org/hib_docs/v3/reference/en/html_single/#objectstate-querying-executing-tuples


----------



## paidopoieo (11. Apr 2006)

hallo gumble, 
danke fuer deine antwort....
hab meinen code jetzt geaendert: und bekomme trotzdem Fehlermeldung:


```
public Collection[] getPeptideSeqAndProteinName() {
		/* will hold the peptides we are going to return later */
		Collection proPep = new ArrayList();
		/* a Hibernate session */
		Session session = null;
		/* we always need a transaction */
		Transaction tx = null;

		/* get session of the current thread */
		session = HibernateSessionFactory.currentSession();

		tx = session.beginTransaction();
		List tmpProPep = session.createQuery(
				"select pept.peptide_seq, prot.name_of_protein from Peptide pept, Protein prot where pept.length_of_peptideseq = 4 and prot.protein_id = pept.peptide_id").list();
		for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {
			Object[] tuple = (Object[]) iter.next();
//			String peptSeq = tuple[0].toString();
//	        String proteinName = tuple[1].toString();
	        proPep.add(tuple);
			
		}
		tx.commit();

		return (Collection[]) proPep.toArray(new Peptide[0]);
	}
```

und die Form sieht folgendermassen aus: 


```
public class PeptideEditForm extends ActionForm {
	
	private Peptide peptide;
	private Peptide[] peptideSet = new Peptide[0];
	private Collection[] protPeptSet = new Collection[0];
	
	
	public Collection[] getProtein_Peptide() {
		return protPeptSet;
	}
	
	public void setProtein_Peptide(Collection[] protPept) {
		this.protPeptSet = protPept;
	}
	..............
.........
```

folgende Fehlermeldung


```
ava.lang.ArrayStoreException
	java.lang.System.arraycopy(Native Method)
	java.util.ArrayList.toArray(ArrayList.java:304)
```

dankeschoen fuer deine Hilfe
mfg


----------



## Murray (11. Apr 2006)

Das ist letzendlich immer noch der gleiche Fehler: in der Ergebnisliste stehen Object-Arrays, keine Peptide-Objekte. Nach  Deiner Änderung tritt der Fehler nur später auf, nämlich dann, wenn versucht wird, die Elemente der temporären Liste in ein Peptide-Array zu schreiben.


----------



## Murray (11. Apr 2006)

Das ist letzendlich immer noch der gleiche Fehler: in der Ergebnisliste stehen Object-Arrays, keine Peptide-Objekte. Nach  Deiner Änderung tritt der Fehler nur später auf, nämlich dann, wenn versucht wird, die Elemente der temporären Liste in ein Peptide-Array zu schreiben.


----------



## paidopoieo (11. Apr 2006)

ok, sorry, aber ich steh auf der Leitung.......
was muss ich dann machen, das aus diesen Objekt elementen Peptide elemente werden....


----------



## Murray (11. Apr 2006)

Probier doch mal

```
for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {
         Object[] tuple = (Object[]) iter.next(); 
         for ( int i=0; i<tuple; i++) {
            System.out.println( "tuple #" + i + ": " + tuple[i].getClass().getName() + " -> " + tuple[i].toString());
         }
}
```
Dann siehst Du, wie das Ergebnis aufgebaut ist. Ich vermute mal stark, dass tuple[0] das Peptiode-Objekt ist.


----------



## paidopoieo (11. Apr 2006)

ok, du hast recht.... 
aber ich weiss nicht wie ich mein Problem damit loese....
sorry


----------



## Murray (11. Apr 2006)

Wenn tuple[0] jeweils das Peptide-Objekt ist, dann müsste es doch so gehen:

```
for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {
         Object[] tuple = (Object[]) iter.next();
         proPep.add( (Peptide)(tuple[0]));
      }
```


----------



## paidopoieo (11. Apr 2006)

hi, 
noch ne bloede frage, und was retouniere ich dann


----------



## Murray (11. Apr 2006)

Was willst Du denn zurückgeben? Nur die Peptide? Oder auch die Proteine?


----------



## paidopoieo (11. Apr 2006)

hi, 
nein beides, 
die sequenz ist ein attribut der tabelle Peptide und der Name ein attribut aus der Tabelle Protein...
also beides.....
und das dann in einer jsp seite anzeigen lassen....nur das eben weiss ich auch noch nicht wie das geht....


----------



## Gumble (12. Apr 2006)

Welchen Typ haben die beiden Objekte? "pept.peptide_seq" und "prot.name_of_protein"

Was ich nur nicht ganz verstehe, was "return (Collection[]) proPep.toArray(new Peptide[0]); " genau soll. Reicht es nicht einfach die Liste zurueckzugeben? "return proPep" Und in die Liste die richtigen Objekte speichern. (z.B. die Stringpaare)[/code]


----------



## paidopoieo (12. Apr 2006)

hi gumble,
peptide_seq ist vom Typ String aus der Klasse Peptide
name_of_protein ist ebenfalls vom Typ String aus der Klasse Protein

ja, so ganz check ich das auch nicht, den das habe ich aus dem internet uebernommen......
hab das jetzt geaendert, oder glaub zumindest geaendert wie du das gesagt hast....


```
public Collection getPeptideSeqAndProteinName() {
		/* will hold the peptides we are going to return later */
		Collection proPep = new ArrayList();
		/* a Hibernate session */
		Session session = null;
		/* we always need a transaction */
		Transaction tx = null;

		/* get session of the current thread */
		session = HibernateSessionFactory.currentSession();

		tx = session.beginTransaction();
		List tmpProPep = session.createQuery(
				"select pept.peptide_seq, prot.name_of_protein from Peptide pept, Protein prot where pept.length_of_peptideseq = 4 and prot.protein_id = pept.peptide_id").list();
		for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {
			Object[] tuple = (Object[]) iter.next();
//			String peptSeq = tuple[0].toString();
//	        String proteinName = tuple[1].toString();
			proPep.add((Peptide)(tuple[0])); 
			proPep.add((Protein)(tuple[1]));
			
		}
		tx.commit();

		return proPep;
	}
```

meine form auf: 


```
public class PeptideEditForm extends ActionForm {
	
//	private Peptide peptide;
//	private Peptide[] peptideSet = new Peptide[0];
	private Collection protPeptSet;	
	
	public Collection getProtein_Peptide() {
		return protPeptSet;
	}
	
	public void setProtein_Peptide(Collection protPept) {
		this.protPeptSet = protPept;
	}
```

und meine Action ist gleich geblieben:

```
public class Protein_PeptideAction extends Action {
	
	   
	
	public ActionForward execute(
		    ActionMapping mapping,
		    ActionForm form,
		    HttpServletRequest request,
		    HttpServletResponse response)
		  {
			PeptideEditForm peptideEditForm = (PeptideEditForm) form;
		    
		    PeptideManager peptideManager = new PeptideManager();
		    
		    peptideEditForm.setProtein_Peptide(peptideManager.getPeptideSeqAndProteinName());
		    return mapping.findForward("showProtein_Peptide");
		  }
```

nur weiss ich nicht ob das stimmt und wie ich die collection auf die jsp seite bekomme...
vielen herzlichen dank fuer deine hilfe...

mfg


----------



## Gumble (12. Apr 2006)

Hi, paidopoieo
na so spaet noch am basteln? 

hm, nein, so geht das nicht:
proPep.add((Peptide)(tuple[0]));
proPep.add((Protein)(tuple[1])); 
Dein select-statement waehlt 2 Spalten (=Attribute) aus den 2 Tabellen aus, und die sind doch vom Typ String und nicht vom Typ Peptide bzw Protein? Und da die inhaltlich ein Paar bilden, wuerde ich sie nicht getrennt in der Liste speichern.
String[] tupel = (String[]) iter.next(); 
also pepPropList.add(tupel);

Wie du nun die Liste in ein Strutsform kriegst, weiss ich nicht. Hab bisher nur mit JSF gearbeitet. Ne simple jsp/jstl loesung waere mal [untested]

```
<jsp:useBean id="ppBean" class="my.package.PpBean" scope="session" />
<c:forEach var="pepProp" items="${ppBean.pepPropList}">
  <tr> 
    <td> 
      ${pepProp[0]}
    </td>
    <td> 
      ${pepProp[1]}
    </td>
  </tr> 
</c:forEach>
```
Wobei das ppBean Object ein simples Sessionbean ist und das Attribut "pepPropList" haben muss (=die Liste).


----------



## paidopoieo (12. Apr 2006)

hi, gumble,
shit, es tut mir leid...war mein fehler..
die sind natuerlich nicht vom Typ String...sondern
peptide_seq ist von Typ Peptide und name_of_protein ist vom Typ Protein......

tut mir leid.......


----------



## paidopoieo (12. Apr 2006)

ok, vielleicht doch zeit zum Bett gehen... :wink:  *gg*


----------



## Murray (12. Apr 2006)

Du willst also eine Liste von Ergebnissen zurückliefern, in der jedes Ergebnis aus zwei verschiedenen Objekten besteht. Dazu bietet es sich normalerweise an, eine Wrapper-Klasse zu definieren, die die beiden verschiedenen Objekte (bei dir Peptide und Protein) kapselt. Die Ergebnisliste ist dann eine einfache Liste dieser Wrapper-Objekte.

Für mich sieht es so aus, als ginge Deine erste Lösung (also der Code im ursprünglichen Post) bereits in dieser Richtung; die Klasse Protein_Peptide könnte so ein Wrapper sein. Was fehlt, ist dann nur die Wandlung der Ergebnis-Tupel in diesen Wrapper. 

Poste doch mal den Code von Protein_Peptide, dann sollte sich klären lassen, was man mit den Tupeln machen mussen, um daraus Protein_Peptide-Objekte zu machen.


----------



## paidopoieo (12. Apr 2006)

Hi,
meine Protein_Peptide Klasse ist einfach zusammengesetzt aus den variabeln und den dazugehoerigen gettern und settern der beiden klassen Peptide und Protein. Ich weisss nicht ob das so stimmt...wahrscheinlich eh nicht: 


```
public abstract class AbstractProtein_Peptide implements Serializable {
	
//================================ Peptide Properties =====================================	 
	/** The composite primary key value. */
    private java.lang.Integer peptide_id;

    /** The value of the simple peptide_seq property. */
    private java.lang.String peptide_seq;

    /** The value of the simple startpos_in_proteinseq property. */
    private java.lang.Integer startpos_in_proteinseq;
    
    /** The value of the simple endpos_in_proteinseq property. */
    private java.lang.Integer endpos_in_proteinseq;
    
    /** The value of the simple length_of_peptideseq property. */
    private java.lang.Integer length_of_peptideseq;
    
    /** The value of the simple expect_val property. */
    private java.lang.Integer expect_val;

//================================ Protein Properties =====================================   
    /** The composite primary key value. */
    private java.lang.Integer protein_id;

    /** The composite primary key value. */
    private java.lang.String accession_code;

    /** The value of the simple name_of_protein property. */
    private java.lang.String name_of_protein;

    /** The value of the simple length_of_protein property. */
    private java.lang.Integer length_of_protein;
    
    
//=================================== Getters and Setters ==================================

	public java.lang.String getAccession_code() {
		return accession_code;
	}

	public void setAccession_code(java.lang.String accession_code) {
		this.accession_code = accession_code;
	}

	public java.lang.Integer getEndpos_in_proteinseq() {
		return endpos_in_proteinseq;
	}

	public void setEndpos_in_proteinseq(java.lang.Integer endpos_in_proteinseq) {
		this.endpos_in_proteinseq = endpos_in_proteinseq;
	}

	public java.lang.Integer getExpect_val() {
		return expect_val;
	}

	public void setExpect_val(java.lang.Integer expect_val) {
		this.expect_val = expect_val;
	}

	public java.lang.Integer getLength_of_peptideseq() {
		return length_of_peptideseq;
	}

	public void setLength_of_peptideseq(java.lang.Integer length_of_peptideseq) {
		this.length_of_peptideseq = length_of_peptideseq;
	}

	public java.lang.Integer getLength_of_protein() {
		return length_of_protein;
	}

	public void setLength_of_protein(java.lang.Integer length_of_protein) {
		this.length_of_protein = length_of_protein;
	}

	public java.lang.String getName_of_protein() {
		return name_of_protein;
	}

	public void setName_of_protein(java.lang.String name_of_protein) {
		this.name_of_protein = name_of_protein;
	}

	public java.lang.Integer getPeptide_id() {
		return peptide_id;
	}

	public void setPeptide_id(java.lang.Integer peptide_id) {
		this.peptide_id = peptide_id;
	}

	public java.lang.String getPeptide_seq() {
		return peptide_seq;
	}

	public void setPeptide_seq(java.lang.String peptide_seq) {
		this.peptide_seq = peptide_seq;
	}

	public java.lang.Integer getProtein_id() {
		return protein_id;
	}

	public void setProtein_id(java.lang.Integer protein_id) {
		this.protein_id = protein_id;
	}

	public java.lang.Integer getStartpos_in_proteinseq() {
		return startpos_in_proteinseq;
	}

	public void setStartpos_in_proteinseq(java.lang.Integer startpos_in_proteinseq) {
		this.startpos_in_proteinseq = startpos_in_proteinseq;
	}
    
}
```


```
public class Protein_Peptide extends AbstractProtein_Peptide implements Serializable {
	
	private Set protPept;

	/**
	 * Simple constructor of Protein_Peptide instances.
	 */
	public Protein_Peptide () {
		protPept = new HashSet();
	}
	
	
	public Set getProtein_Peptides () {
		return protPept;
	}

	public void setProtein_Peptide (Set protPept) {
		this.protPept = protPept;
	}

}
```

dankeschoen 
mfg


----------



## Murray (12. Apr 2006)

Wenn man Protein_Peptide so verwendet, dann müsste es so gehen:


```
public Protein_Peptide[] getPeptideSeqAndProteinName() {
      /* will hold the entries we are going to return later */
      List proPep = new ArrayList();
      /* a Hibernate session */
      Session session = null;
      /* we always need a transaction */
      Transaction tx = null;

      /* get session of the current thread */
      session = HibernateSessionFactory.currentSession();

      tx = session.beginTransaction();
      List tmpProPep = session.createQuery(
      "select pept.peptide_seq, prot.name_of_protein from Peptide pept, Protein prot where pept.length_of_peptideseq = 4 and           prot.protein_id = pept.peptide_id").list();
      for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {

         //--- fetch one tuple from result-set
         Object[] tuple = (Objtect[])(iter.next());

         //--- split tuple into Peptide and Protein
        Peptide peptide = (Peptide)(tuple[0]);
        Protein protein = (Protein)(tuple[1]);

         //--- create wrapper
        Protein_Peptide pp = new Protein_Peptide();

         //--- set Peptide-attributes in wrapper
         pp.setPeptide_id( peptide.getPeptide_id());
         pp.setPeptide_seq( peptide.getPeptide_seq());
         pp.setStartpos_in_proteinseq( peptide.getStartpos_in_proteinseq());
         pp.setEndpos_in_proteinseq( peptide.getEndpos_in_proteinseq());
         pp.setLength_of_peptideseq( peptide.getLength_of_peptideseq());
         pp.setExpected_val( peptide.getExpected_val());

         //--- set Protein-attributes in wrapper
         pp.setProtein_id( protein.getProtein_id());
         pp.setAccession_code( protein.getAccession_code());
         pp.setName_of_protein( protein.getName_of_protein());
         pp.setLength_of_protein( protein.getLength_of_protein());


         //--- insert wrapper into temporary result-list
         proPep.add( pp);

      }
      tx.commit();

      return (Protein_Peptide[]) proPep.toArray(new Protein_Peptide[proPep.size()]);
   }
```

Man könnte sich noch etwas Schreibkram sparen, wenn man den Wrapper etwas anders baut und nicht alle Properties dupliziert, sondern das per Aggregation löst: Protein_Peptide würde dann nur zwei Member enthalten (Protein und Peptide), und die Getter und Setter würden an die jeweiligen Getter und Setter delegiert.


----------



## paidopoieo (12. Apr 2006)

hallo murray,
dankeschoen, hab deinen code jetzt probiert, und bekomme in Zeile 21 folgende Fehlermeldung:


```
java.lang.ClassCastException: java.lang.String
```

mfg


----------



## Murray (12. Apr 2006)

Hmm, hatte ich nicht etliche Posts früher gefragt, ob tuple[0] vom Typ Peptide ist? Aber egal, dann vergiss das; dann wird das Tupel wohl nur genau die beiden von Dir selektieren Werte enthalten.

Dann müsste es wohl so aussehen:

```
for (Iterator iter = tmpProPep.iterator(); iter.hasNext();) {

         //--- fetch one tuple from result-set
         Object[] tuple = (Object[])(iter.next());

         //--- create wrapper
        Protein_Peptide pp = new Protein_Peptide();

         //--- set attributes in wrapper
         pp.setPeptide_seq( (String)(tuple[0]));
         pp.setName_of_protein( (String)(tuple[1]));

         //--- insert wrapper into temporary result-list
         proPep.add( pp);

      }
```


----------



## paidopoieo (12. Apr 2006)

hallo murray,
dankeschoen, und sorry fuer die ganzen unannehmlichkeiten....
aber es scheint zu funktionieren.....

jetzt versuch ich das ganze in der jsp seite zu darstellen......
falls da probleme auftreten werd ich mich wieder melden...  :wink: 

mfg


----------



## paidopoieo (12. Apr 2006)

hi murray,
hab meine jsp page zum laufen gebracht, jedoch werden keine eintraege angezeigt, obwohl das select statement funktioniert, habs auf der commandline getestet.....
wollte mal fragen ob der code so stimmt und ob es vielleicht eine moeglichkeit zu debuggen:


```
<%-- start with an iterate over the collection  --%>
	<logic:iterate name="proteinPeptideForm" property="peptides" id="peptide">
	<tr>
		<%-- peptide informations --%>
		<td><bean:write name="peptide" property="peptide_seq" /></td>
		<td><bean:write name="peptide" property="name_of_protein" /></td>
		
		
		<td><html:link action="peptideEdit.do?do=editPeptide" 
					   paramName="peptide" 
					   paramProperty="peptide_id" 
					   paramId="peptide_id">Edit</html:link>
		</td>

		<td><html:link action="proteinShow.do?do=showProtein" 
					   paramName="peptide" 
					   paramProperty="peptide_id" 
					   paramId="peptide_id">Show Protein</html:link>
		</td>
	</tr>
	</logic:iterate> 
	<%-- end interate --%>
```

name: proteinPeptideForm ist wie es im struts-config file definiert ist....

mfg


----------



## paidopoieo (13. Apr 2006)

hi murray, 
habs hinbekommen, funktioniert so wie ich es will....
dankeschoen nochmals fuer deine grossartige hilfe.....

hab noch einen schoenen abend

mfg


----------

