Converter + Zugriff auf DAO und EntityManager

kiwie

Mitglied
Hi,
ich habe folgendes Problem:
ich möchte ein SelectOneMenu verwenden, um ne auswahl zu geben und das dann zu speichern.
da habe ich gelesen, dass man nen converter braucht, um die Objekte da richtig rauszubekommen. Nun hab ich einen Converter geschrieben. Allerdings dann auch erfahren, dass es erst am JSF 2.2 möglich ist Beans in diesen zu injecten. (Ich verwende nur die jsf-api von com.sun.faces version 2.0.2 und das upgraden scheint ziemlich kompliziert.. da geht dann gar nichts mehr).
also habe ich versucht das anders zu machen. wenn ich die verwendete DAO im converter selbst mit new ... instanziiere, dann klappt das soweit. Nur in der DAO selbst bekommt er dann keinen EntityManager, der eigentlich automatisch injected sein müsste. (und bei andren methodenaufrufen über einen Service klappt das auch. die DAO ist also in Ordnung).

Der Converter (ein paar von meinen Lösungsversuchen sind da auskommentiert):
Java:
//@Component
//@Scope("request")
@FacesConverter("com.barbeit.web.converter.StudentConverter")
public class StudentConverter implements Converter{

//	@Autowired //hat nicht funktioniert
	private static StudentDAOImpl studentDAO = new StudentDAOImpl();

	
    @Override
//    @Transactional (readOnly = false)
    public Object getAsObject(FacesContext context, UIComponent component, String newValue) {
    	// Convert the unique String representation of Student to the actual Student object.
    	//Ausgaben zum Ueberpruefen:
    	System.out.println("new value(als String): "+ newValue);
    	String s;
    	if (studentDAO == null){
    		s="keine studentDAO";
    	} else { s="okay";}
    	System.out.println("studentDAO: " + s);
    	
    	int i = Integer.parseInt(newValue);
    	System.out.println("als Integer: "+i);

    	return studentDAO.getById(Integer.parseInt(newValue));
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
    	// Convert the Student object to its unique String representation.
        return String.valueOf(((Student) value).getId());
    }

	public static StudentDAO getStudentDAO() {
		return studentDAO;
	}

	public static void setStudentDAO(StudentDAOImpl studentDAO) {
		StudentConverter.studentDAO = studentDAO;
	}  
}

ein Teil aus der Entity:
Java:
	// This must return true for another Student object with same id.
	@Override
    public boolean equals(Object other) {
    	if (other == null) {
            return false;
        } else if (!(other instanceof Student)) {
            return false;
        } else if (Integer.toString(((Student) other).getId()).equals(Integer.toString(this.id))) {
            return true;
        } else {
            return false;
        }
    }

    // This must return the same hashcode for every Student object with the same id.
	@Override
    public int hashCode() {
        return id != 0 ? this.getClass().hashCode() + id : super.hashCode();
    }

ein Teil aus der xhtml:
HTML:
<h:outputLabel for="StudentMenu" value="Student (bis Student ueberg. funkt.): *" /> 
        	<p:selectOneMenu id="StudentMenu" value="#{effortService.stud}" effect="fade">  
           		<f:selectItem itemLabel="Select One" itemValue="" />
            	<f:selectItems value="#{effortService.students}" var="Student" 
            	itemLabel="#{Student.rzPerson.name}, #{Student.rzPerson.firstName}"/>
        	</p:selectOneMenu>

aus der DAO:
Java:
@Repository("studentDAO")
@Scope(value="request")
public class StudentDAOImpl implements StudentDAO{

	@PersistenceContext
	private EntityManager em;

//getter und setter und andere CRUD methoden

public Student getById(int id) {
		//Ausgaben zum ueberpruefen:
		System.out.println("id: "+ id);
		String s;
    	if (em == null){
    		s="kein EntityManager!";
    	} else { s="okay";}
    	System.out.println("EntityManager: " + s);
    	
		return getEntityManager().find(Student.class, id);
	}

wenn ihr sonst noch infos braucht...
danke schon ma für die mühe...

ach ja ich frag mich auch, ob ich eigentlich wirklich einen Converter brauche? bevor ich einen hatte, konnte ich die Entities immerhin ja anzeigen, nur habe ich da immer nur null herausbekommen beim speichern. Lag das daran, dass der Converter gefehlt hat oder mach ich die ganze mühe umsonst?

Bzw. findet ihr es klüger die JSF version irgendwie zu ändern? (und wenn ja wie stell ich das am geschicktesten an und was muss ich so ändern?)
 
Zuletzt bearbeitet:

tandraschko

Mitglied
Die Injection in Converter haben sie gestrichen und würde eh nur mit CDI gehen - nicht mit Spring.
Somit musst du für Spring eine Lösung finden - Spicken könntest du bei CODI und den Code für Spring adaptieren.
Falls es sowas nicht im Internet gibt, würde ich es nicht raten, wenn man sich mit den Frameworks intern noch nicht befasst hat.

Ich würde einfach per Hand deine SpringBeans in den Converter holen oder einen abstrakten Converter entwickeln der dir die Injection im Constructor macht (falls sowas mit Spring geht).


Raten würde ich dir trotzdem auf jedenfall JSF bis zur letzten 2.1 Version upzugraden oder gleich auf MyFaces zu gehen - rein von den Performance und den Bugs.
 
Zuletzt bearbeitet:

sence

Bekanntes Mitglied
Wenn du den Converter nur an einer Stelle verwendest, kann du auch ohne DAO arbeiten und ein wenig Performance gewinnen, in dem auf die Liste mittels ELResolver direkt zu greifst:

Java:
public Object getAsObject(FacesContext context, UIComponent component, String newValue) {

FacesContext context = FacesContext.getCurrentInstance();
EffortService ES = (EffortService) context.getELContext().getELResolver().getValue(context.getELContext(), null,"effortService");

if(ES != null)
    for(Studen S : ES.students)
         if(S.id == Integer.parseInt(newValue))
             return S;

return null; // nicht gefunden
}
 
Zuletzt bearbeitet:

kiwie

Mitglied
Danke @sence: das hat soweit geklappt, aber ich befürchte, dass ich den converter auch wo anders noch brauchen werde... hast du da auch so ne idee?
@tandraschko: per hand hab ich's ja versucht mit der DAO, aber der entitymanager in der DAO wird dann nicht injected... weißt du warum das so ist? wird der auch nur injected wenn die DAO selbst durch Injection gebaut wurde?
puh mit abstraktem converter hab ich mich noch gar nicht befasst. hast du da zufällig n gutes tut :)?
 

sence

Bekanntes Mitglied
ich gebe Dir nur den Denkansatz, wenn du es nicht selbst heraus findest gib bescheid :)

Schau nach woher der "Call" kommt, bzw in welcher Umgebung der Converter angefordert wurde, dementsprechend
holst du die benötigte Bean und die Liste

Abstrakt
if(condition == 1)
-> Bean x holen
-> Liste aus Bean x holen
else if(condition == 2)
-> Bean y holen
-> Liste aus Bean y holen

du hast hierbei zwar eine "harte" Verdrahtung, je nach Anzahl der zu ladenden Elemente (und zusätzlicher RAM usw...) macht es einen rießen Unterschied aus im Gegensatz zu der DB basierenden Abfrage.

VG
 

kiwie

Mitglied
nach deinem tipp hab ichs so versucht:

Java:
context = FacesContext.getCurrentInstance();
        
        if (component.getId() == "StudentMenu"){
        	EffortService ES = (EffortService) context.getELContext().getELResolver().getValue(context.getELContext(), null,"effortService");
	        if(ES != null){
	            for(Student S : ES.getStudents()){
	                 if(S.getId() == Integer.parseInt(newValue)){
	                     return S;
	                 }
	            }
	        }
	        return null; // nicht gefunden
        } else {
       
        return null; // keine komponente gefunden
        }

leider funktioniert die bedingung im if so nicht und er springt gleich nach unten auf return null;
obwohl ich mir auch das getId(); mal habe ausgeben lassen und da StudentMenu heraus kam....
 

sence

Bekanntes Mitglied
Java:
if (component.getId() == "StudentMenu"){

wie werden in Java zwei Strings miteinander verglichen :- )
component.getId().equals("StudentMenu");
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
G JSF JSF 2.3 Converter injection/persistence context -> null Web Tier 2
M Converter für SelectOneMenu Web Tier 3
P JSF Converter Web Tier 3
H JSF Converter selectoneitem Web Tier 9
H JSF Problem mit Converter Web Tier 2
M JSF Converter für String to List<String> Web Tier 2
D JSF Converter erstellen Web Tier 2
H JSF SelectOneMenu und der Converter Web Tier 3
T JSF Eigener Converter wird nur für Eingabekomponenten aufgerufen? Web Tier 3
A ice:inputText Converter Problem Web Tier 2
M JSF 2 Global Converter Web Tier 4
Y JSF: Entites in SelectItems und Converter Web Tier 6
S JSF Enum Converter Web Tier 1
W RichFaces converter in orderingList wirft exception Web Tier 5
W JSF Probleme mit Zugriff zur Managed Bean Web Tier 11
R JSF Zugriff für Helpdesk-Mitarbeiter Web Tier 15
O JSF Zugriff auf entfernte Dateien Web Tier 11
S [JSF] Zugriff auf Bean (Eclispe,JBoss) Web Tier 12
J Servlet Zugriff Servlet Web Tier 11
H JSF Fehler bei Zugriff auf f:attribute Web Tier 2
R Zugriff Validator in Tabelle (ui:repeat) auf andere Felder Web Tier 2
M JSF Zugriff auf mehrere Formulareinträge in einem Validator Web Tier 9
A JSF xhtml parameter / zugriff auf value Web Tier 2
R Zugriff auf Session direkt auf JSF-Seite Web Tier 2
R Zugriff auf geschützten Bereich ohne Authentifizierung Web Tier 10
M JSF Kein Zugriff auf ManagedBeans, nach JSF Migration von 1.2 nach 2.0 Web Tier 4
K Struts request Zugriff Web Tier 4
S Lesender Zugriff auf Datei im Webprojekt Web Tier 2
D Servlets vor direktem Zugriff schützen Web Tier 2
M Zugriff aus eigenen Tags auf Struts Value Stack Web Tier 2
S Problem mit Servlet und Zugriff auf Orace XE Datenbank Web Tier 2
J JSP -> DB Zugriff? Web Tier 4
M JSF Designfrage bzgl. DB-Zugriff Web Tier 9

Ähnliche Java Themen

Neue Themen


Oben