Vaadin 7.0.1 Combobox with JPAContainer and FieldGroup

(Sorry if this is a bit of a newb question)

I have two JPAContainers, one for an Employee class/table and one for Language class/table. An employee can have a selected language.

I am trying to create an Employee editing form with a combobox for the language selection and FieldGroup to handle the binding and creation.

I can get the drop down to include the entries from the Languages table via the JPAContainer but it will not display the value already in place in the Employee record. What am I doing wrong?

  //Key parts of code....

    private JPAContainer<Employee> employees;
    private JPAContainer<Language> languages;
    
    FormLayout formLayout = new FormLayout();
    		    		
    formFieldGroup = new FieldGroup(employeeItem);
    		
    Field<?> firstName = formFieldGroup.buildAndBind("First name", "firstName");
    Field<?> lastName = formFieldGroup.buildAndBind("Last name", "lastName");
    Field<?> userName = formFieldGroup.buildAndBind("Username", "userName");
    Field<?> fullName = formFieldGroup.buildAndBind("Full name", "fullName");
    Field<?> initials = formFieldGroup.buildAndBind("Initials", "initials");
    		
    ComboBox language = new ComboBox("Language",languages);
    language.setContainerDataSource(languages);
    language.setItemCaptionPropertyId("languageName");
    language.setFilteringMode(FilteringMode.CONTAINS);
    language.setImmediate(true);
    		
    formFieldGroup.bind(language, "language");
    				
    firstName.addValidator(new BeanValidator(Employee.class, "firstName"));
    lastName.addValidator(new BeanValidator(Employee.class, "lastName"));
    firstName.addValidator(new BeanValidator(Employee.class, "userName"));
    lastName.addValidator(new BeanValidator(Employee.class, "fullName"));
    lastName.addValidator(new BeanValidator(Employee.class, "initials"));
    
    formLayout.addComponent(userName);
    formLayout.addComponent(fullName);
    formLayout.addComponent(firstName);
    formLayout.addComponent(lastName);
    formLayout.addComponent(initials);
    formLayout.addComponent(language);
		
     // A few details of the domain classes
    @Entity
    @Table(name="Employees")
    public class Employee   extends BaseEntity
    {
	private static final long	serialVersionUID	= 1L;
	
	@Id 
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="EmployeeID")
	private Integer		employeeID;

        ...

	@ManyToOne 
	@JoinColumn(name="LanguageID",updatable=false)
	private Language	language;
        ...}

    @Entity
    @Table(name="Languages")
    public class Language  extends BaseEntity
    {

	@Id 
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="LanguageID")
	private Integer languageID;
	
	@Column(name="LangaugeName")
	private String 	languageName;
	
        ... }

Hi Michael,

JPAContainer item IDs are the same as the ID in the database, which means that using a JPAContainer in a select/combo box causes the value of the select to be the ID of the row in the database and not the POJO itself, as is expected by your Employee entity POJO. Adding a SingleSelectConverter to your combo box should fix your problem:

language.setConverter(new SingleSelectConverter(language));

As a side note, you are setting the container data source for the language combo box twice. First in the constructor, and then explicitly on the next line. You can remove one of them without affecting anything.

HTH,
/Jonatan

Cheers Jonatan.

Figured I was doing something noddy. Hadn’t been able to find much on the SingleSelectConverter so didn’t get how to tie it together.

Live and learn!

The resetting the container source should have been removed, one of those dumb things you try when you are stuck!

Regards
Michael.

Hi!

It seems that I’ve got the same problem. Instead of using a container as datasource, I’ve added my three items by
[font=Courier New]

combo.addItem(0);
combo.setItemCaption(0, “test0”);
combo.addItem(1);
combo.setItemCaption(1, “test1”);
combo.addItem(2);
combo.setItemCaption(2, “test2”);

[/font]

I’m binding the comboboxes to a fieldgroup which in turn is using an sqlcontainer. There are textfields which uses the values provided by the sqlcontainer, but the combobox does not. I was about trying this solution, but I can’t find any SingleSelectConverter anywere.

Any ideas?

Thanks in advance,
Michael

  1. You are not using a JPAContainer as datasource for the Combobox , so this answer provided by Jonatan Kronqvist does not apply.
  2. If you want to use a Combobox like in you’re example to display a property, the ItemID you add should match the value (and type) of the property (provided by the sqlcontainer in your case).

It appears SingleSetConverter is somehow broken in Vaadin 7.1.0 as indicated in this thread: https://vaadin.com/forum#!/thread/3619129

I’m facing exactly the same issue as the original writer of this thread. Could anyone offer us any other workaround (than using SingleSelectConverter) on how to set the current value (language) for ComboBox/Select when editing an entity (employee)?

My temp fix was just rewriting a singleselectconverter with the correct method signatures and use it instead of SingleSelectConverter. Here is the lightly modified code …


import java.util.Locale;

import com.vaadin.addon.jpacontainer.EntityContainer;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.ui.AbstractSelect;

public class SingleSelectConverterCorrected<T> implements Converter<Object, T> {

    private final AbstractSelect select;

    public SingleSelectConverterCorrected(AbstractSelect select) {
        this.select = select;
    }

    @SuppressWarnings("unchecked")
    private EntityContainer<T> getContainer() {
        return (EntityContainer<T>) select.getContainerDataSource();
    }

  

    public Class<T> getModelType() {
        return getContainer().getEntityClass();
    }

    public Class<Object> getPresentationType() {
        return Object.class;
    }

	@Override
	public T convertToModel(Object value, Class<? extends T> targetType, Locale locale)
			throws com.vaadin.data.util.converter.Converter.ConversionException {
		 if (value != select.getNullSelectionItemId()) {
	            return getContainer().getEntityProvider().getEntity(getContainer(),
	                    value);
	        } else {
	            return null;
	        }
	}

	@Override
	public Object convertToPresentation(T value, Class<? extends Object> targetType, Locale locale)
			throws com.vaadin.data.util.converter.Converter.ConversionException {
		if (value != null) {
            return getContainer().getEntityProvider().getIdentifier(value);
        }
        return select.getNullSelectionItemId();
	}

}

hello! I have a next code:

ComboBox cbLanguageTemplate = new ComboBox();

final List<A_DICT_LANGUAGES> att2 = dataBase.getBeansLanguage();
        for(A_DICT_LANGUAGES r: att2){
             cbLanguageTemplate.addItem(r.getID_LANGUAGE());
             cbLanguageTemplate.setItemCaption(r.getID_LANGUAGE(),r.getNAME_LANGUAGE());
            
        }

I need get my ID_LANGUAGE from Combobox when I choise item:

cbLanguageTemplate.addValueChangeListener(new Property.ValueChangeListener() {
            @Override
            public void valueChange(Property.ValueChangeEvent valueChangeEvent) {
               String h = cbLanguageTemplate.getItemCaption(valueChangeEvent.getProperty().getValue());
                System.out.println("--------->" + h);
            }
        });

But I get NAME_LANGUAGE. How I can get ID_LANGUAGE?

valueChangeEvent.getProperty().getValue()

Thank you very much! It works!

Hello, I’m Facing a similar problem with my JPAContainer Combobox and FieldGroup.

I’m Using Vaadin 7.1.15 and JPAContainer 3.1.1
When i try to bind my combobox with a property the value gets changed, but the combobox visually remains unchanged…

I’m using SingleSelectConverter…

What could be the problem?

        types = JPAContainerFactory.make(ProductType.class, "inventory");
        cbType.setImmediate(true);
        cbType.setTextInputAllowed(false);
        cbType.setNullSelectionAllowed(false);
        cbType.setInvalidAllowed(true);
        cbType.setConverter(new SingleSelectConverter<ProductType>(cbType));
        cbType.setContainerDataSource(types);
        cbType.setItemCaptionPropertyId("name");

---------

            FieldGroup fg = new FieldGroup(item);
            fg.bind(cbType, "productType");
            System.out.println(cbType.getValue());

The Combo gets the value set in the Item.

You can try
markAsDirty()
on the combobox or
markAsDirtyRecursive()
on parent layout.

Sadly i’ve tried that and it doesn’t work…