[jboss-user] [JBoss Seam] - Re: EntityConverter: Entity Manager not found
mgrouch
do-not-reply at jboss.com
Mon Aug 6 10:27:47 EDT 2007
EntityConverter and <s:convertEntity /> have serious limitation in both
Seam 2.0 and 1.2.1.GA - they require entity to be Seam managed.
I've solved this by not using <s:convertEntity />.
Instead I've created generic class EntitySelector which returns
list of Ids and converter. I'd extend this class for each dropdown (you probably would want to have a backing bean for dropdown anyway).
public abstract class EntitySelector<ID extends Serializable, ENTITY extends Serializable> implements Serializable {
|
| private final static Log log = LogFactory.getLog(EntitySelector.class);
|
| private static final int DEFAULT_SIZE = 0;
| private EntitySelectorConverter<ID, ENTITY> converter;
|
| private Map<String, ENTITY> lookupMap = new HashMap<String, ENTITY>(DEFAULT_SIZE);
| private List<ID> keyList = new ArrayList<ID>(DEFAULT_SIZE);
| private List<ENTITY> values = new ArrayList<ENTITY>(DEFAULT_SIZE);
|
| public static Object getId(Object bean) {
| Class<?> clazz = bean.getClass();
| log.trace("bean.getClass(): #0", clazz);
| if (!clazz.isAnnotationPresent(javax.persistence.Entity.class)) {
| // this better be instrumented proxy class
| clazz = clazz.getSuperclass();
| log.trace("bean.getClass().getSuperclass(): #0", clazz);
| }
| return Entity.forClass(clazz).getIdentifier(bean);
| }
|
| public ID getId(ENTITY bean) {
| return (ID) EntitySelector.getId((Object) bean);
| }
|
| public EntitySelector() {
| converter = new EntitySelectorConverter<ID, ENTITY>(this);
| }
|
| public void init(List<ENTITY> entities, Comparator<ENTITY> comparator) {
| if (entities != null) {
| values = entities;
| if (comparator != null) {
| Collections.sort(values, comparator);
| }
| final int size = values.size();
| lookupMap = new HashMap<String, ENTITY>(size);
| keyList = new ArrayList<ID>(size);
| for (ENTITY entity : entities) {
| ID key = getId(entity);
| String strKey = key.toString();
| lookupMap.put(strKey, entity);
| keyList.add(key);
| }
| }
| }
|
| @WebRemote
| public Map<String, ENTITY> getLookupMap() {
| return lookupMap;
| }
|
| @WebRemote
| public List<ID> getKeyList() {
| return keyList;
| }
|
| @WebRemote
| public List<ENTITY> getValues() {
| return values;
| }
|
| @WebRemote
| public ENTITY getByKey(String strKey) {
| ENTITY entity = null;
| if (lookupMap != null) {
| entity = lookupMap.get(strKey);
| }
| return entity;
| }
|
| public EntitySelectorConverter<ID, ENTITY> getConverter() {
| return converter;
| }
| }
public class EntitySelectorConverter<ID extends Serializable, ENTITY extends Serializable>
| implements javax.faces.convert.Converter, Serializable {
|
| private final static Log log = LogFactory.getLog(EntitySelectorConverter.class);
|
| private EntitySelector<ID, ENTITY> entitySelector;
|
| public EntitySelectorConverter(EntitySelector<ID, ENTITY> selector) {
| log.trace("EntitySelectorConverter selector=#0", selector);
| entitySelector = selector;
| }
|
| public String getAsString(FacesContext facesContext, UIComponent cmp,
| Object entity) throws ConverterException {
| if (entity == null) {
| return null;
| }
| ID id = entitySelector.getId((ENTITY) entity);
| log.trace("EntitySelectorConverter getAsString=#0 id=#1", entity, id);
| return id.toString();
| }
|
| public Object getAsObject(FacesContext facesContext, UIComponent cmp,
| String value) throws ConverterException {
| ENTITY entity = entitySelector.getByKey(value);
| log.trace("EntitySelectorConverter getAsObject=#0, entity=#1", value, entity);
| return entity;
| }
| }
This is how you would use it
@Name("timeZones")
| public class TimeZoneBean extends EntitySelector<String, TimeZone> {
|
| @Create
| public void create() {
| List<TimeZone> timeZones = ...
| init(timeZones, null);
| }
| }
And source tag:
<ui:component xmlns="http://www.w3.org/1999/xhtml"
| xmlns:s="http://jboss.com/products/seam/taglib"
| xmlns:ui="http://java.sun.com/jsf/facelets"
| xmlns:f="http://java.sun.com/jsf/core"
| xmlns:a="https://ajax4jsf.dev.java.net/ajax"
| xmlns:h="http://java.sun.com/jsf/html"
| xmlns:w="http://facelets-tags.com/tags"
| xmlns:rich="http://richfaces.ajax4jsf.org/rich">
| <h:selectOneMenu id="#{id}" styleClass="formtext" required="#{required}" value="#{value}" converter="#{timeZones.converter}" rendered="#{empty rendered ? true : rendered}">
| <s:selectItems value="#{timeZones.values}" var="timeZoneVar" noSelectionLabel="#{noSelectionLabel}" hideNoSelectionLabel="#{hideNoSelectionLabel}"
| label="#{timeZoneVar.timeZoneId}" />
| </h:selectOneMenu>
| </ui:component>
Please, let me know what you think about this approach.
Thanks
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4071208#4071208
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4071208
More information about the jboss-user
mailing list