Seam 3 entityConverter
gonzalad May 30, 2011 6:21 AMHello,
Is there an entityConverter for Seam 3 ?
I've found the following information :
- a draft I think here (didn't tested it though)
- this forum post Seam3SentityConverter but it requires extending from a base entity object.
Anyway, in the meantime, I've used the following converter (I'm using it with Seam managed persistence context).
I's a really rough version.
package com.natixis.sigma.jsf;
import javax.enterprise.context.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.inject.Inject;
@RequestScoped
@FacesConverter("entityConverter")
public class EntityConverter implements Converter {
@Inject
private EntityIdentifierStore entityIdentifierStore;
public Object getAsObject(final FacesContext facesContext, final UIComponent component,
final String id) {
return entityIdentifierStore.get(id);
}
public String getAsString(final FacesContext context, final UIComponent comp, final Object entity) {
return entityIdentifierStore.put(entity);
}
}
public class EntityIdentifierStore implements Serializable {
private List<Identifier> store;
@Inject
private EntityManager entityManager;
@PostConstruct
public void create() {
store = new ArrayList<Identifier>();
}
public Object get(String key) {
try {
Identifier identifier = store.get(new Integer(key));
return identifier.find(entityManager);
} catch (IndexOutOfBoundsException e) {
return null;
}
}
public String put(Object entity) {
Identifier identifier = createIdentifier(entity);
if (!store.contains(identifier)) {
store.add(identifier);
}
return ((Integer) store.indexOf(identifier)).toString();
}
private Identifier createIdentifier(Object entity) {
return new Identifier(entity, entityManager);
}
}
package com.natixis.sigma.jsf;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.EntityManager;
@SuppressWarnings("serial")
public class Identifier implements Serializable {
public Identifier(Object entity, EntityManager entityManager) {
this(getEntityClass(entity.getClass()), entityManager
.getEntityManagerFactory().getPersistenceUnitUtil()
.getIdentifier(entity));
}
public Identifier(Class clazz, Object id) {
if (clazz == null || id == null) {
throw new IllegalArgumentException("Id and clazz must not be null");
}
this.clazz = clazz;
this.id = id;
}
private Class clazz;
private Object id;
public Class getClazz() {
return clazz;
}
public Object getId() {
return id;
}
@Override
public boolean equals(Object other) {
if (other instanceof Identifier) {
Identifier that = (Identifier) other;
if (id == null || clazz == null) {
throw new IllegalArgumentException(
"Class and Id must not be null");
} else {
return this.getId().equals(that.getId())
&& this.getClazz().equals(that.getClazz());
}
}
return false;
}
private static Class getEntityClass(Class clazz) {
while (clazz != null && !Object.class.equals(clazz)) {
if (clazz.isAnnotationPresent(Entity.class)) {
return clazz;
} else {
clazz = clazz.getSuperclass();
}
}
return null;
}
public Object find(EntityManager entityManager) {
return entityManager.getReference(getClazz(), getId());
}
}
Sample usage (if you're not using Primefaces, just replace p:selectOneMenu with h:selectOneMenu:
<p:selectOneMenu value="#{portefeuilleBean.criteria.devise}">
<f:converter converterId="entityConverter"/>
<f:selectItems value="#{devises}" var="devise"
itemLabel="#{devise.libelle}" itemValue="#{devise}" />
</p:selectOneMenu>