Dozer NullPointerException on deep-mapping with custom getter - dozer

Im getting this exception:
Field mapping error -->
MapId: null
Type: null
Source parent class: com.ParentObject
Source field name: field1
Source field type: class com.OnOff1BitEnum
Source field value: OFF
Dest parent class: com.SubParent
Dest field name: subParent.field2
Dest field type: java.lang.Boolean java.lang.NullPointerException
at org.dozer.util.ReflectionUtils.invoke(ReflectionUtils.java:270)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.getDeepSrcFieldValue(GetterSetterPropertyDescriptor.java:116)
at org.dozer.propertydescriptor.GetterSetterPropertyDescriptor.getPropertyValue(GetterSetterPropertyDescriptor.java:69)
at org.dozer.fieldmap.FieldMap.getDestValue(FieldMap.java:141)
This is the mapping field:
<mapping>
<class-a>com.ParentObject</class-a>
<class-b>com.SubParent</class-b>
<field custom-converter="com.OnOffEnumToBooleanConverter">
<a>field1</a>
<b get-method="isField2">subParent.field2</b>
</field>
</mapping>
The version of dozer i am using is 5.4.0
UPDATE:
Added the converter code to this post.
When i put a break point here this is not being reached
public class OnOffEnumToBooleanConverter implements org.dozer.CustomConverter {
/**
* {#inheritDoc}
*/
#Override
public Object convert(Object dest, Object src, Class<?> destClass, Class<?> srcClass) {
if (src == null) {
return null;
}
if (src instanceof com.OnOff1BitEnum) {
boolean canonicalObject;
if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.ON) {
canonicalObject = true;
} else if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.OFF) {
canonicalObject = false;
} else { // Unreachable Code To Test
throw new MappingException("Converter " + this.getClass().getCanonicalName() + " used incorrectly. Arguments passed in were: "
+ dest + " and " + src);
}
return canonicalObject;
}
}

Perhaps it happens because you are missing "set configuration", try specifying it explicitly and see if that solves it or a different error happens, e.g.
<field custom-converter="com.OnOffEnumToBooleanConverter">
<a>field1</a>
<b get-method="isField2" set-method="field2">subParent.field2</b>
</field>
UPDATE:
I had to properly format your java code to be able to read...here is the problem you have "if and else" for a boolean value...there is no 3rd condition...just carefully look at it:
if (src instanceof com.OnOff1BitEnum)
{
boolean canonicalObject;
if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.ON)
{
canonicalObject = true;
}
else
{
if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.OFF)
{
canonicalObject = false;
}
else
{ // Unreachable Code To Test
throw new MappingException("Converter " + this.getClass().getCanonicalName()
+ " used incorrectly. Arguments passed in were: " + dest + " and " + src);
}
}
return canonicalObject;
}
That's the evil of "if else construct" that has no brackets in your original code.
Also your "convert" method returns Object...so your "boolean canonicalObject" has to be "Boolean canonicalObject" not primitive type.
Should be:
#Override
public Object convert(Object dest, Object src, Class<?> destClass, Class<?> srcClass)
{
if (src instanceof com.OnOff1BitEnum)
{
if ((com.OnOff1BitEnum) src == com.OnOff1BitEnum.ON)
{
return Boolean.TRUE;
}
else
{
return Boolean.FALSE;
}
}
return null;
}

Related

How do you cast a Unity.Object into a generic class member?

I am a decades-old C programmer. Unity is my first foray into modern C and I find myself pleasantly surprised - but some of the subtleties of the language have escaped me.
First a technical question: What is the right way to store a Unity Object in a generic class? In the example below I get the following error:
Assets/scripts/MediaTest.cs(49,44): error CS0030: Cannot convert type `UnityEngine.Texture2D' to `T'
Second the real question: What is a better approach to loading a set of textures?
Thanks in advance for your help
/*
* MediaTest.cs
*
* Pared down generic class test
*
*/
using System.Collections; // Load IEnumerable
using System.Collections.Generic; // Load Dictionary
using System.Text.RegularExpressions; // Load Regex
using UnityEngine; // Load UnityEngine.Object
public class MediaTest<T> : IEnumerable where T : UnityEngine.Object {
private Dictionary<string, MediaContent> _dict =
new Dictionary<string, MediaContent>();
private class MediaContent {
public string path { get; set; }
public T item { get; set; }
public MediaContent(string path, T item) {
this.path = path;
this.item = item;
}
}
// Indexer to return a UnityEngine.Object by filename
public T this[string name] {
get { return (T)_dict[name].item; }
}
// Convert a path to just the filename
public string Basename(string path) {
return new Regex(#"^.*/").Replace(path, "");
}
// Iterate through the filenames (keys) to the stored objects
public IEnumerator GetEnumerator() {
foreach (string name in _dict.Keys) {
yield return name;
}
}
// Read in the Resource at the specified path into a UnityEngine.Object
public void Load(string path, bool load=false) {
string name = Basename(path);
if (this.GetType() == typeof(Media<Texture2D>) && IsStill(name)) {
T item = (load) ? (T)Resources.Load<Texture2D>(path) : null;
_dict[name] = new MediaContent(path, item);
return;
}
if (this.GetType() == typeof(Media<AudioClip>) && IsAudio(name)) {
T item = (load) ? (T)Resources.Load<AudioClip>(path) : null;
_dict[name] = new MediaContent(path, item);
return;
}
}
// The real code uses Regex.Match on the file extension for supported types
public bool IsStill(string name) { return true; }
public bool IsAudio(string name) { return true; }
}
Here is the working code with updates from the comments. Thanks derHugo!
public void Load(string path, bool load=false) {
// Translate the filesystem path to a Resources relative path by removing both
// The */Resources prefix and the filename extention
Regex re_path = new Regex(#".*/Resources/");
Regex re_ext = new Regex(#"\.\w+$");
string relpath = re_ext.Replace(re_path.Replace(path, ""), "");
// Create an asset name from the path
string name = System.IO.Path.GetFileName(relpath);
// Skip this file if it doesn't match our type
if ( (typeof(T) == typeof(Texture2D) && IsStill(path)) ||
// (typeof(T) == typeof(Video) && IsVideo(path)) ||
(typeof(T) == typeof(AudioClip) && IsAudio(name))) {
T item = (load) ? Resources.Load(relpath) as T : null;
_dict[name] = new MediaContent(path, item);
}
}

Mybatis can set value with reflection?

Mybatis can set value with reflection?
I have a class , and it has a property , it's setter is protected . So I have to use reflection to set this value ? Mybatis can work ?
yes, mybatis use reflect to set value.
in Reflator.java(mybatis 3.3.0), mybatis will config set method.
private void addSetMethods(Class<?> cls) {
Map<String, List<Method>> conflictingSetters = new HashMap<String, List<Method>>();
Method[] methods = getClassMethods(cls);
for (Method method : methods) {
String name = method.getName();
if (name.startsWith("set") && name.length() > 3) {
if (method.getParameterTypes().length == 1) {
name = PropertyNamer.methodToProperty(name);
addMethodConflict(conflictingSetters, name, method);
}
}
}
resolveSetterConflicts(conflictingSetters);
}
if your class do not have set method, when addSetFields it will add new SetInvoker for the field:
private void addSetField(Field field) {
if (isValidPropertyName(field.getName())) {
setMethods.put(field.getName(), new SetFieldInvoker(field));
setTypes.put(field.getName(), field.getType());
}
}
and the SetFieldInvoker is like this:
/**
* #author Clinton Begin
*/
public class SetFieldInvoker implements Invoker {
private Field field;
public SetFieldInvoker(Field field) {
this.field = field;
}
#Override
public Object invoke(Object target, Object[] args) throws IllegalAccessException, InvocationTargetException {
field.set(target, args[0]);
return null;
}
#Override
public Class<?> getType() {
return field.getType();
}
}
the DefaultResultSetHandler calls BeanWrapper's setBeanProperty method will call getSetInvoker
private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
try {
Invoker method = metaClass.getSetInvoker(prop.getName());
Object[] params = {value};
try {
method.invoke(object, params);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
} catch (Throwable t) {
throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass() + "' with value '" + value + "' Cause: " + t.toString(), t);
}
}
the whole call chain maybe like this:
DefaultSqlSession##selectList -->SimpleExecutor##doQuery --> SimpleStatementHandler##query --> DefaultResultSetHandler##handleResultSets

JPA Dynamic Order By with Criteria API

I have the below code snippet for dynamic sorting using JPA Criteria API
Root<Employee> root = criteriaQuery.from(Employee);
Join<Employee, Project> joinProject =
root.join(Employee_.projectList, JoinType.LEFT);
if (sortDirection.equals("asc")) {
criteriaQuery.orderBy(cb.asc(root.get(sortField)));
If I am passing an attribute of Employee entity to order by statement, it works without any hitch, however if an attribute of Project entity is passed to order by statement, exception is thrown stating that
The attribute [projectName] is not present in the managed type
because projectName is an attribute of Projectentity which is joined with Employee using joinProject. In order by statement I am using root.get(sortField). if it is joinProject.get(sortField), it would work fine when attributes of Project are being passed to order by statement.
My questions are
How could I modify my Order By statement in order to cater all the attributes which being passed?
Do I need to conditionally check which attribute and accordingly use if conditions or are there better ways of doing this?
Appreciate insight into this.
A specific approach for a simple scenario (predetermined one-level only joins) may be something like this:
Root<Employee> root = criteriaQuery.from(Employee.class);
Join<Employee, Project> joinProject = root.join(Employee_.projectList, JoinType.LEFT);
Class<?> baseClass = fieldTypeMap.get(sortField);
From<?, ?> from;
if(baseClass == Employee.class)
{
from = root;
}
else if(baseClass == Project.class)
{
from = joinTeam;
}
else ...
Expression<?> expr = from.get(sortField);
if(sortDirection.equals("asc"))
{
criteriaQuery.orderBy(cb.asc(expr));
}
...
where fieldTypeMap is something like:
private final static Map<String, Class<?>> fieldTypeMap = new HashMap<>();
static {
fieldTypeMap.put("employeeName", Employee.class);
fieldTypeMap.put("projectName", Project.class);
...
}
However, this is quick and dirty, ugly and unmaintainable.
If you want a generic approach, things may get a bit complex.
Personally, I'm using my own classes built on top of EntityManager, CriteriaBuilder and Metamodel, which provides dynamic filtering and multi-sorting features.
But something like this should be meaningful enough:
protected static List<Order> buildOrderBy(CriteriaBuilder builder, Root<?> root, List<SortMeta> sortList)
{
List<Order> orderList = new LinkedList<>();
for(SortMeta sortMeta : sortList)
{
String sortField = sortMeta.getSortField();
SortOrder sortOrder = sortMeta.getSortOrder();
if(sortField == null || sortField.isEmpty() || sortOrder == null)
{
continue;
}
Expression<?> expr = getExpression(root, sortField);
if(sortOrder == SortOrder.ASCENDING)
{
orderList.add(builder.asc(expr));
}
else if(sortOrder == SortOrder.DESCENDING)
{
orderList.add(builder.desc(expr));
}
}
return orderList;
}
protected static Expression<?> getExpression(Root<?> root, String sortField)
{
ManagedType<?> managedType = root.getModel();
From<?, Object> from = (From<?, Object>) root;
String[] elements = sortField.split("\\.");
for(String element : elements)
{
Attribute<?, ?> attribute = managedType.getAttribute(element);
if(attribute.getPersistentAttributeType() == PersistentAttributeType.BASIC)
{
return from.get(element);
}
from = from.join(element, JoinType.LEFT);
managedType = EntityUtils.getManagedType(from.getJavaType());
}
return from;
}
This way the join is based on sort field, which is now a dotted-path-expr like "projectList.name" or "office.responsible.age"
public static <X> ManagedType<X> getManagedType(Class<X> clazz)
{
try
{
return getMetamodel().managedType(clazz);
}
catch(IllegalArgumentException e)
{
return null;
}
}
public static Metamodel getMetamodel()
{
return getEntityManagerFactory().getMetamodel();
}
public static EntityManagerFactory getEntityManagerFactory()
{
try
{
return InitialContext.doLookup("java:module/persistence/EntityManagerFactory");
}
catch(NamingException e)
{
throw new RuntimeException(e.getMessage(), e);
}
}
to make it work on a webapp, you have to declare contextual references on web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<display-name>my_app_name</display-name>
...
<persistence-context-ref>
<persistence-context-ref-name>java:module/persistence/EntityManager</persistence-context-ref-name>
<persistence-unit-name>my_pu_name</persistence-unit-name>
</persistence-context-ref>
<persistence-unit-ref>
<persistence-unit-ref-name>java:module/persistence/EntityManagerFactory</persistence-unit-ref-name>
<persistence-unit-name>my_pu_name</persistence-unit-name>
</persistence-unit-ref>
</web-app>
update
I don't know about how EclipseLink handles grouping, but also Hibernate does not perform joins (actually, conditions on joins) correctly in some case.
In example, when all these conditions are met:
querying an entity (as Root/From) that is part of a class hierarchy (and not a leaf) based on SINGLE_TABLE
joining/getting a property of a subclass
joining/getting by property name (String) instead of Attribute
To workaround the issue I always resolve property name to an Attribute and reuse joins already "walked" (did I say things may get complicated?):
public class MetaDescriptor extends BusinessObject implements Serializable, MemberEx, ColumnDescriptor
{
private static final long serialVersionUID = 1L;
#BusinessKey
protected final Attribute<?, ?> attribute;
#BusinessKey
protected final MetaDescriptor parent;
protected List<MetaDescriptor> childList;
protected final Type<?> elementType;
...
protected MetaDescriptor(Attribute<?, ?> attribute, MetaDescriptor parent)
{
this.attribute = attribute;
this.parent = parent;
if(attribute instanceof SingularAttribute)
{
SingularAttribute<?, ?> singularAttribute = (SingularAttribute<?, ?>) attribute;
elementType = singularAttribute.getType();
}
else if(attribute instanceof PluralAttribute)
{
PluralAttribute<?, ?, ?> pluralAttribute = (PluralAttribute<?, ?, ?>) attribute;
elementType = pluralAttribute.getElementType();
}
else
{
elementType = null;
}
}
public static MetaDescriptor getDescriptor(ManagedType<?> managedType, String path)
{
return getDescriptor(managedType, path, null);
}
public static MetaDescriptor getDescriptor(From<?, ?> from, String path)
{
if(from instanceof Root)
{
return getDescriptor(((Root<?>) from).getModel(), path);
}
return getDescriptor(from.getJavaType(), path);
}
public static MetaDescriptor getDescriptor(Class<?> clazz, String path)
{
ManagedType<?> managedType = EntityUtils.getManagedType(clazz);
if(managedType == null)
{
return null;
}
return getDescriptor(managedType, path);
}
private static MetaDescriptor getDescriptor(ManagedType<?> managedType, String path, MetaDescriptor parent)
{
if(path == null)
{
return null;
}
Entry<String, String> slice = StringUtilsEx.sliceBefore(path, '.');
String attributeName = slice.getKey();
Attribute<?, ?> attribute;
if("class".equals(attributeName))
{
attribute = new ClassAttribute<>(managedType);
}
else
{
try
{
attribute = managedType.getAttribute(attributeName);
}
catch(IllegalArgumentException e)
{
Class<?> managedClass = managedType.getJavaType();
// take only if it is unique
attribute = StreamEx.of(EntityUtils.getMetamodel().getManagedTypes())
.filter(x -> managedClass.isAssignableFrom(x.getJavaType()))
.flatCollection(ManagedType::getDeclaredAttributes)
.filterBy(Attribute::getName, attributeName)
.limit(2)
.collect(Collectors.reducing((a, b) -> null))
.orElse(null);
if(attribute == null)
{
return null;
}
}
}
MetaDescriptor descriptor = new MetaDescriptor(attribute, parent);
String remainingPath = slice.getValue();
if(remainingPath.isEmpty())
{
return descriptor;
}
Type<?> elementType = descriptor.getElementType();
if(elementType instanceof ManagedType)
{
return getDescriptor((ManagedType<?>) elementType, remainingPath, descriptor);
}
throw new IllegalArgumentException();
}
#Override
public <T> Expression<T> getExpression(CriteriaBuilder builder, From<?, ?> from)
{
From<?, Object> parentFrom = getParentFrom(from);
if(attribute instanceof ClassAttribute)
{
return (Expression<T>) parentFrom.type();
}
if(isSingular())
{
return parentFrom.get((SingularAttribute<Object, T>) attribute);
}
return getJoin(parentFrom, JoinType.LEFT);
}
private <X, T> From<X, T> getParentFrom(From<?, ?> from)
{
return OptionalEx.of(parent)
.map(x -> x.getJoin(from, JoinType.LEFT))
.select(From.class)
.orElse(from);
}
public <X, T> Join<X, T> getJoin(From<?, ?> from, JoinType joinType)
{
From<?, X> parentFrom = getParentFrom(from);
Join<X, T> join = (Join<X, T>) StreamEx.of(parentFrom.getJoins())
.findAny(x -> Objects.equals(x.getAttribute(), attribute))
.orElseGet(() -> buildJoin(parentFrom, joinType));
return join;
}
private <X, T> Join<X, T> buildJoin(From<?, X> from, JoinType joinType)
{
if(isSingular())
{
return from.join((SingularAttribute<X, T>) attribute, joinType);
}
if(isMap())
{
return from.join((MapAttribute<X, ?, T>) attribute, joinType);
}
if(isSet())
{
return from.join((SetAttribute<X, T>) attribute, joinType);
}
if(isList())
{
return from.join((ListAttribute<X, T>) attribute, joinType);
}
if(isCollection())
{
return from.join((CollectionAttribute<X, T>) attribute, joinType);
}
throw new ImpossibleException();
}
public Order buildOrder(CriteriaBuilderEx builder, From<?, ?> from, SortOrder direction)
{
if(direction == null)
{
return null;
}
Expression<?> expr = getExpression(builder, from);
return direction == SortOrder.ASCENDING ? builder.asc(expr) : builder.desc(expr);
}
}
with this construct, I can now safely:
public static List<Order> buildOrderList(CriteriaBuilderEx builder, From<?, ? extends Object> from, List<SortMeta> list)
{
return StreamEx.of(list)
.nonNull()
.map(x -> buildOrder(builder, from, x.getSortField(), x.getSortOrder()))
.nonNull()
.toList();
}
public static Order buildOrder(CriteriaBuilderEx builder, From<?, ? extends Object> from, String path, SortOrder direction)
{
if(path == null || path.isEmpty() || direction == null)
{
return null;
}
MetaDescriptor descriptor = MetaDescriptor.getDescriptor(from, path);
if(descriptor == null)
{
return null;
}
return descriptor.buildOrder(builder, from, direction);
}
If sortField exists only in one entity:
try{
path = root.get(sortField);
}catch (IllegalArgumentException e){
path = joinProject.get(sortField);
}
criteriaQuery.orderBy(cb.asc(path));

Binding ObservableCollection to datagrid in MVVM

Im new to XAML, i am trying to bind ObservableCollection to datagrid in MVVM.
I want to get notified when CollectionChanged. But its throwing null exception.
Please let me know when im going wrong. Thanks in advance.
The following is Code behind for viewModel:
public class MainwindowViewModel : INotifyPropertyChanged
{
MyObject myObj;
ObservableCollection<MyObject> _ocObj;
public MainwindowViewModel()
{
_ocObj = new ObservableCollection<MyObject>();
myObj = new MyObject();
myObj.ID = 0;
myObj.Name = "Name";
_ocObj.Add(myObj);
_ocObj.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_ocMyobj_CollectionChanged);
}
void _ocMyobj_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
System.Windows.MessageBox.Show("propeties changed # " + e.NewStartingIndex.ToString()
+ " old items starting # " + e.OldStartingIndex + " olditems count " + e.OldItems.Count.ToString()
+ " action " + e.Action.ToString());
}
public ObservableCollection<MyObject> ocObj
{
get { return _ocObj; }
set
{
PropertyChanged(this, new PropertyChangedEventArgs("ocMyobj"));
}
}
public string Name
{
get { return myObj.Name; }
set
{
if (value !=null)
{
myObj.Name = value;
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
}
public int ID
{
get { return myObj.ID; }
set
{
if (myObj.ID != value)
{
myObj.ID = value;
PropertyChanged(this, new PropertyChangedEventArgs("ID"));
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
public class MyObject
{
public string Name { get; set; }
public int ID { get; set; }
}
Below is XAML:
<Window.Resources>
<vm:MainwindowViewModel x:Key="someObj"/>
</Window.Resources>
<DataGrid ItemsSource="{Binding ocObj}" DataContext="{Binding Source={StaticResource someObj}}" AutoGenerateColumns="True" />
Take a look at the documentation on the NotifyCollectionChangedEventArgs class. Note that the OldItems object only "Gets the list of items affected by a Replace, Remove, or Move action." What this means is that for other actions, OldItems will be null.
Therefore, if an Add action is performed against your ObservableCollection, OldItems is null (and valid). Just perform a check for it in your code, such as:
System.Windows.MessageBox.Show("propeties changed # " + e.NewStartingIndex.ToString()
+ " old items starting # " + e.OldStartingIndex + " olditems count " +
(e.OldItems == null ? "0" : e.OldItems.Count.ToString())
+ " action " + e.Action.ToString());

primefaces (3.2) autocomplete pojo

I am trying to implement PF Autocomplete component (v3.2) with POJO. Things work fine when a user selects an entry from the possible drop down options provided. However, the scenario where a user enters some text into the input field and simply hits enter does not work well for me.
If a user simply enters some text to the autocomplete input box and hits enter, all I have to do is redirect them to a new page with 1 query parameter. I noticed that if I hit enter before AutoComplete has a chance to show suggestions, then the redirect happens just fine. Once drop down suggestions are shown, hitting enter simply clears the input box.
I would expect something like this to work just fine, so I must be doing something silly.
<h:form>
<p:autoComplete id="globalAutoComplete" value="#{autoCompleteBackingBean.selectedResult}" completeMethod="#{autoCompleteBackingBean.globalSearch}" var="aResult" itemValue="#{aResult}" converter="autoCompleteConverter" queryDelay="200" maxResults="6" minQueryLength="3">
<p:column>
#{aResult.label} <br/> #{aResult.desc} <span class='ui-icon #{aResult.icon} autocompleteResultsIcon'/>
</p:column>
</p:autoComplete>
<p:commandButton id="submitAutoComplete" type="submit" icon="ui-icon-suitcase" action="#{autoCompleteBackingBean.doRedirect}"/>
</h:form>
Converter:
public Object getAsObject(FacesContext fc, UIComponent uic, String value) {
if (value == null || value.length() == 0 ) {
return null;
}
Object obj = null;
try {
List<AutoComplete> results = AutoCompleteBackingBean.getResults();
for (AutoComplete aResult : results){
if((aResult.getDreRef()).equals(value))
return aResult;
}
} catch (Exception e) {
System.err.println("AutoCompleteConverter getAsObject Error: " + e);
}
if (obj == null) {
AutoComplete empty = new AutoComplete();
empty.setDreRef(value);
return empty;
}
return obj;
}
public String getAsString(FacesContext fc, UIComponent uic, Object object) {
if (object == null) {
return null;
}
Class entityClass = getEntityClass();
String value = null;
if (entityClass.isInstance(object)) {
try {
value = ((AutoComplete)object).getDreRef();
}catch (Exception e){
System.err.println("AutoCompleteConverter getAsString Error: " + e);
value = "Unable to obtain String from Object";
}
}
else {
value = "AutoCompleteConverter.getAsString(): Object " + object + " is of type "
+ object.getClass().getSimpleName() + "; expected type: "
+ entityClass.getSimpleName();
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, value, null));
}
return value;
}
Backing bean:
private AutoComplete selectedResult = null;
//getter and setter
public String doRedirect() {
System.out.println("doRedirect()");
return "entities.jsf?query=" + selectedResult.getDreRef() + "&faces-redirect=true";
}