Primefaces 5 SelectOneMenu + Hibernate + Wildfly and Entities

Die letzten zwei Tage waren wieder eine Suche nach dem richtigen Weg. Im Normalfall würde sich mein JPA Manager um eine performante Art und Weise kümmern meine Daten zwischen zu lagern oder neu zu laden. Hibernate geht leider eine etwas andere Logik vor und cached nicht lange genug die Entities vor. Das heißt bei einem Neuaufruf über eine andere Bean wird nicht vom Application Server geladene Inhalte übertragen sondern die Abfrage erneut gestartet. Somit wäre ein flushen im Entity Manager nach dem updaten von Inhalten nur optional.

Es ist ziemlich einfach wenn man weiß woran es liegt. Und zwar wird bei Entities eine equals Methode geladen z.b.

package de.kuw.jee.core.verwaltung;

import java.io.Serializable;

import javax.persistence.*;

import java.util.List;
import java.util.logging.Logger;


/**
 * The persistent class for the virtual_domains database table.
 * 
 */
@Entity
@Table(name="virtual_domains")
@NamedQuery(name="VirtualDomain.findAll", query="SELECT v FROM VirtualDomain v")
public class VirtualDomain implements Serializable {
	private static final long serialVersionUID = 1L;
	private static final Logger log = Logger.getLogger(VirtualDomain.class.getName());

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;

	private boolean active;

	private boolean deleted;

	private String directory;

	@Column(name="domain_type")
	private String domainType;

	private String name;

	//bi-directional many-to-one association to SysDomain
	@OneToMany(mappedBy="virtualDomain")
	private List sysDomains;

	//bi-directional many-to-one association to VirtualAlias
	@OneToMany(mappedBy="virtualDomain")
	private List virtualAliases;

	//bi-directional many-to-one association to BillCustomer
	@ManyToOne
	@JoinColumn(name="customer_id")
	private BillCustomer billCustomer;

	//bi-directional many-to-one association to VirtualUser
	@OneToMany(mappedBy="virtualDomain")
	private List virtualUsers;

	public VirtualDomain() {
	}

	public int getId() {
		return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public boolean getActive() {
		return this.active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public boolean getDeleted() {
		return this.deleted;
	}

	public void setDeleted(boolean deleted) {
		this.deleted = deleted;
	}

	public String getDirectory() {
		return this.directory;
	}

	public void setDirectory(String directory) {
		this.directory = directory;
	}

	public String getDomainType() {
		return this.domainType;
	}

	public void setDomainType(String domainType) {
		this.domainType = domainType;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List getSysDomains() {
		return this.sysDomains;
	}

	public void setSysDomains(List sysDomains) {
		this.sysDomains = sysDomains;
	}

	public SysDomain addSysDomain(SysDomain sysDomain) {
		getSysDomains().add(sysDomain);
		sysDomain.setVirtualDomain(this);

		return sysDomain;
	}

	public SysDomain removeSysDomain(SysDomain sysDomain) {
		getSysDomains().remove(sysDomain);
		sysDomain.setVirtualDomain(null);

		return sysDomain;
	}

	public List getVirtualAliases() {
		return this.virtualAliases;
	}

	public void setVirtualAliases(List virtualAliases) {
		this.virtualAliases = virtualAliases;
	}

	public VirtualAlias addVirtualAlias(VirtualAlias virtualAlias) {
		getVirtualAliases().add(virtualAlias);
		virtualAlias.setVirtualDomain(this);

		return virtualAlias;
	}

	public VirtualAlias removeVirtualAlias(VirtualAlias virtualAlias) {
		getVirtualAliases().remove(virtualAlias);
		virtualAlias.setVirtualDomain(null);

		return virtualAlias;
	}

	public BillCustomer getBillCustomer() {
		return this.billCustomer;
	}

	public void setBillCustomer(BillCustomer billCustomer) {
		this.billCustomer = billCustomer;
	}

	public List getVirtualUsers() {
		return this.virtualUsers;
	}

	public void setVirtualUsers(List virtualUsers) {
		this.virtualUsers = virtualUsers;
	}

	public VirtualUser addVirtualUser(VirtualUser virtualUser) {
		getVirtualUsers().add(virtualUser);
		virtualUser.setVirtualDomain(this);

		return virtualUser;
	}

	public VirtualUser removeVirtualUser(VirtualUser virtualUser) {
		getVirtualUsers().remove(virtualUser);
		virtualUser.setVirtualDomain(null);

		return virtualUser;
	}

	@Override
	public boolean equals(Object obj) {
		if(obj != null) {
			log.info("Equals action in VirtualDomain for obj: " 
					 + obj.toString());
		}
		return super.equals(obj);
	}
}

Zum testen habe ich die equals Methode rausgezogen um zu sehen was geprüft wird im selectOneMenu von Primefaces. Und wie ich es mir gedacht habe. Wildfly weiß nicht mehr das die Daten in der view schon existieren und werden daher nochmal aus der DB geladen und somit natürlich einen anderen Hash zugeordnet. Um diesen Fehler des: „value not valid“ zu vermeiden müsst ihr die Bean die ViewScoped per CDI Injected wird die Wertetabelle rausziehen z.B.


Der Primefaces

package de.kuw.jee.verwaltung.converter;

import java.util.logging.Logger;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;

import de.kuw.jee.core.verwaltung.VirtualDomain;
import de.kuw.jee.verwaltung.mb.DomainBean;

@FacesConverter("domainConverter")
public class DomainConverter implements Converter {
	private Logger log = Logger.getLogger(DomainConverter.class.getName());
	
	@Inject
	private DomainBean domainBean;
	
	private int id;
	
	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String value) {
		VirtualDomain dom = null;
        id = Integer.valueOf(value);
        if(value != null && id > 0) {
        	for(VirtualDomain tmp : domainBean.getDomains()) {
        		if(tmp.getId() == id) {
        			dom = tmp;
        		}
        	}
        	
        	log.info("Object is: " + dom.toString() );
        }
        
        return dom;
    }

	@Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
    	String returnVal = "";
    	if(value instanceof VirtualDomain) {
    		 VirtualDomain dom = (VirtualDomain) value;
    		 returnVal = String.valueOf(dom.getId());
    	} else {
    		returnVal = "";
    	}
    	log.finest("GetAsString is: " + returnVal);
        return returnVal;
    }
}

Sobald ihr das beachtet, und aus bestehenden Datasets lest, werdet ihr den Fehler der falschen Hashed und equals Fehler nicht mehr bekommen.

viel Spaß beim ausprobieren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert