Problem with selected value of Select component

Hello,

I know that this has appeared many times in the forum but still I cannot get a solution with my case.

I have a Select component inside a Form and within a createField() method:

@Override
	public Field createField(Item item, Object propertyId, Component uiContext) {
		// Identify the fields by their Property ID.
		String pid = (String) propertyId;
		Field f;

		if ("realNotreal".equals(pid)) {
			BeanContainer<Integer, Lookup> beans = new BeanContainer<Integer, Lookup>(Lookup.class);
			beans.setBeanIdProperty("valueIntvalue");

			beans.addAll(entityManager.getLookupByValueType("real_not_real"));

			f = new Select(pid, beans);
			((AbstractSelect) f).setItemCaptionPropertyId("valueDescription");
		}
		
		f.setCaption(Messages.getString(pid));

		return f;
	}

The property “valueIntvalue” is of type: int

Problem:The database returns the Integer 2 but the value is not automatically selected in the component. I know that the Select component goes through all the container and makes comparisons with the item ids and the value that comes from the database. In my case, there is an item with id = 2 but still it’s not selected.

Any ideas?

Thank you in advance,

Jim

Hi Jim,

contains the Lookup-bean a method getValueIntvalue() that returns an integer?
Can you post your Lookup-bean please?

Greetings,
Pascal

Pascal hi, thanks for taking some time to reply. Here’s the bean:


package jimb.property.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.NamedQueries;

@Entity
@NamedQueries( {
		@NamedQuery(name = "getLookup", query = "SELECT l FROM Lookup l"),
		@NamedQuery(name = "getLookupByValueId", query = "SELECT l FROM Lookup l WHERE l.valueId = :valueId"),
		@NamedQuery(name = "getLookupByValueType", query = "SELECT l FROM Lookup l WHERE l.valueType = :valueType"),
		@NamedQuery(name = "getLookupByValueIntvalue", query = "SELECT l FROM Lookup l WHERE l.valueIntvalue = :valueIntvalue"),
		@NamedQuery(name = "getLookupByValueDescription", query = "SELECT l FROM Lookup l WHERE l.valueDescription = :valueDescription") })
public class Lookup implements Serializable {
	@Id
	@Column(name = "value_id")
	private int valueId;

	@Column(name = "value_type")
	private String valueType;

	@Column(name = "value_intvalue")
	private int valueIntvalue;

	@Column(name = "value_description")
	private String valueDescription;

	private static final long serialVersionUID = 1L;

	public Lookup() {
		super();
	}

	public int getValueId() {
		return this.valueId;
	}

	public void setValueId(int valueId) {
		this.valueId = valueId;
	}

	public String getValueType() {
		return this.valueType;
	}

	public void setValueType(String valueType) {
		this.valueType = valueType;
	}

	public int getValueIntvalue() {
		return this.valueIntvalue;
	}

	public void setValueIntvalue(int valueIntvalue) {
		this.valueIntvalue = valueIntvalue;
	}

	public String getValueDescription() {
		return this.valueDescription;
	}

	public void setValueDescription(String valueDescription) {
		this.valueDescription = valueDescription;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + valueId;
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (!(obj instanceof Lookup)) {
			return false;
		}
		Lookup other = (Lookup) obj;
		 if (valueId != other.valueId) {
			return false;
		 }
		return true;
	}

}

Hi Jim,

I don’t think, that the select works with the ID. The BeanContainer-type is Lookup and the property you bind is Integer.

Can you try something like this instead:


...
        if ("realNotreal".equals(pid)) {
            IndexedContrainer beans = new IndexedContainer();
            beans.addContainerProperty("displayName", String.class, "");

            for (Lookup bean : entityManager.getLookupByValueType("real_not_real")) {
                beans.addItem(bean.getValueIntvalue()).getItemProperty("displayName").setValue(bean.getValueDescription());
            }

            f = new Select(pid, beans);
            ((AbstractSelect) f).setItemCaptionPropertyId("valueDescription");
        }
...

In the example the container contains integer-items and not Lookup-items. I don’t tested this code, but it should work.

Greetings,
Pascal

Select does work with the ID of an Item (e.g. setValue(id) or select(id)) and the ID type of the BeanContainer in the original code snippet is Integer as it should be. Also, I believe int ↔ Integer conversions should not be a problem here. Maybe you are mixing up BeanContainer (which lets you specify the ID property or an explicit ID value) with BeanItemContainer which always uses the bean itself as the ID.

Just to make sure: the Select here is not in multi-select mode? If multi-selection is active, the value is a Set of IDs rather than an ID.

The original code looks correct to me, I would suggest stepping through setValue(…) with a debugger to see what goes wrong - probably helps you find the issue faster than analyzing the code on this level if the container does have an item with the correct ID as you say it does…

The Select is single-select as I tested with ((AbstractSelect) f).setMultiSelect(false);

Let me check with the debugger and get back to you…

Pascal I tried your code but it is still not getting the selected item. I will try debugging the setValue() method and get back to you.

Ok, debug results when I added a valueChangeListener listener:

this is at the time of the Select rendering, when the valueChange event is triggered:

items	BeanContainer<IDTYPE,BEANTYPE>  (id=1853)	
	allItemIds	ListSet<E>  (id=1884)	
		array	Object[10]
  (id=1889)	
			[0]
	[b]
Integer  
[/b](id=1078)	
				value	1	
			[1]
	[b]
Integer  
[/b](id=1402)	
				value	2	
			[2]
	null	
			[3]
	null	
			[4]
	null	
			[5]
	null	
			[6]
	null	
			[7]
	null	
			[8]
	null	
			[9]
	null	
	...
beanIdResolver	AbstractBeanContainer$PropertyBasedBeanIdResolver  (id=1829)	
     type	Class<T> (jimb.property.entity.Lookup) (id=2018)	
...
value	[b]
Byte
[/b]  (id=2960)	
     value	1	

So what does this mean, that the incoming value at setValue() is Byte instead of Integer?

Ok, the mistake was revealed with the debugger!

My form datasource, the form ‘bean’ had a ‘byte’ variable instead of an int. I was completely drawn by the integer variable of the Lookup bean so I didn’t consider both variable types. Stupid me!

I changed the byte → int in the form datasource and it was fixed. After the fix, Pascals workaround works even with a faulty theory behind it as Henri points out.

Thank you for your time guys, that was fast and well served!

jim