i want use reflection on generic type
i have this class
package it.ciro.service;
import it.ciro.dao.SysMyAbDao;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* Created by ciro on 09/12/2016.
*/
public class SelectOption<E extends Serializable> {
private SysMyAbDao dao;
private Class<E> entity;
private ArrayList<Class<E>> entityAll;
private Map<String,String> optionList = new HashMap<String,String>();
protected Logger logger;
public SelectOption(SysMyAbDao dao,Class<E> entity,String idName, String labelName ){
logger = Logger.getLogger(this.getClass());
this.dao = dao;
this.entity = entity;
entityAll = dao.findAll();
try{
Method idMethod = this.entity.getMethod(idName);
Method labelMethod = this.entity.getClass().getMethod(labelName);
for (Class<E> single : entityAll) {
optionList.put((String)idMethod.invoke(single),(String)labelMethod.invoke(single));
}
}catch (NoSuchMethodException ex){
ex.printStackTrace();
logger.error(ex.getMessage());
} catch (InvocationTargetException e) {
logger.error(e.getMessage());
} catch (IllegalAccessException e) {
logger.error(e.getMessage());
}
}
public Map<String, String> getOptionList() {
return optionList;
}
}
and in my controller
SelectOption<GeoProvince> selectOption = new SelectOption(geoRegionDao,GeoRegion.class,"idGeoRegion","name");
but i get
java.lang.NoSuchMethodException: java.lang.Class.idGeoRegion()
java search on generic type e not on type that I use in constructor
I expect the search to be made about the type I spend in controller. In GeoRegion class the method exists.
this is SysMyAbDao
public abstract class SysMyAbDao<T, E, Id extends Serializable> {
protected String message;
protected Boolean status;
protected T t ;
protected Logger logger;
protected Long totalRow;
private Class<T> type;
public SysMyAbDao(Class<T> type){
this.type = type;
}
.....
GeoRegion class
public class GeoRegion implements java.io.Serializable {
private int idRegion;
private String name;
private String code;
private Set<GeoProvince> geoProvinces = new HashSet<GeoProvince>(0);
private Set<GeoCity> geoCities = new HashSet<GeoCity>(0);
public GeoRegion() {
}
public GeoRegion(int idRegion) {
this.idRegion = idRegion;
}
public GeoRegion(int idRegion, String name, String code, Set<GeoProvince> geoProvinces, Set<GeoCity> geoCities) {
this.idRegion = idRegion;
this.name = name;
this.code = code;
this.geoProvinces = geoProvinces;
this.geoCities = geoCities;
}
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name="id_region", unique=true, nullable=false)
public int getIdRegion() {
return this.idRegion;
}
public void setIdRegion(int idRegion) {
this.idRegion = idRegion;
}
#Column(name="name")
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
#Column(name="code", unique=true)
public String getCode() {
return this.code;
}
public void setCode(String code) {
this.code = code;
}
#OneToMany(fetch=FetchType.LAZY, mappedBy="geoRegion")
public Set<GeoProvince> getGeoProvinces() {
return this.geoProvinces;
}
public void setGeoProvinces(Set<GeoProvince> geoProvinces) {
this.geoProvinces = geoProvinces;
}
#OneToMany(fetch=FetchType.LAZY, mappedBy="geoRegion")
public Set<GeoCity> getGeoCities() {
return this.geoCities;
}
public void setGeoCities(Set<GeoCity> geoCities) {
this.geoCities = geoCities;
}
}
You have an extra getClass() in this line:
Method labelMethod = this.entity.getClass().getMethod(labelName);
In fact, you are calling getClass() on the Class<E> object. And as the class of Class<E> is not E but java.lang.Class you get the NoSuchMethodException you posted.
Also the instance which you are invoking your method on (single in your case), should be of type E and not of type Class<E>.
Overall you would end up with something like:
public SelectOption(SysMyAbDao<E, ?, ? extends Serializable> dao,
Class<E> entityClass,
String idName,
String labelName) {
this.dao = dao;
this.entityClass = entityClass;
this.entityAll = dao.findAll(); // make sure your SysMyAbDao<E, ?, ?>#findAll() returns a Collection<E>
try{
Method idMethod = this.entityClass.getMethod(idName);
Method labelMethod = this.entityClass.getMethod(labelName);
for (E instance : entityAll) {
optionList.put((String)idMethod.invoke(instance),(String)labelMethod.invoke(instance));
}
} catch (NoSuchMethodException ex){
...
}
}
You are trying to invoke your method on single, which is a Class object.
I don't see any instances of GeoRegion in this code. But in order for this to work, you need to use this method on one of them:
E instance = getSomeObjectFromSomewhere();
optionList.put((String)idMethod.invoke(instance),(String)labelMethod.invoke(instance));
Related
I created a parent class Repo which has methods for insert, delete, display and delete objects in a list. Repo is a generic class. I created a child classes for Repo (like DepartmentRepo class)and pass Department, Employee, etc.. classes. I want perform insert, delete, display and delete operations on any class objects that passed to Repo class.
I need to get the return value of the method "get" which is from Generic class in java. I can only get the method name from Generic here I mention the code files
public class Department {
private long Id;
private String Name;
private String Location;
public Department() {
}
public Department(long id, String name, String location) {
super();
Id = id;
Name = name;
Location = location;
}
public long getId() {
return Id;
}
public void setId(long id) {
Id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
}
import java.util.ArrayList;
import java.util.List;
public class Repo<T, U> {
List<T> list = new ArrayList<T>();
public List<T> getAll() {
return list;
}
public void insert(T obj) {
list.add(obj);
}
public T get(U id) throws NoSuchMethodException, SecurityException {
for (T ele : list) {
if (ele.getClass().getMethod("getId") == id) {
return ele;
}
}
return null;
}
public void delete(U id) throws NoSuchMethodException, SecurityException {
list.remove(get(id));
}
}
public class DepartmentRepo extends Repo<Department, Long>{
}
class MainApi
{
public static void main (String[] args)
{
DepartmentRepo dept = new DepartmentRepo ();
Department ict=new Department(10001,"Dept of ICT","Town");
Department cs=new Department(10002,"Dept of Computer Science","Pampaimadu");
Department bio=new Department(10003,"Dept of Bio Science","Pampaimadu");
Department sats=new Department(10004,"Dept of Statistics","Kurumankadu");
dept.insert(ict);
dept.insert(cs);
dept.insert(bio);
dept.insert(sats);
System.out.println();
dept.getAll();
try{
dept.get(10001);
}
catch(Exception e){
}
}
}
As another solution, and an answer to your comment, you could use elements inheritance, and avoid reflection calls and exceptions.
1- Create an element interface OR class
public interface RepoElement<U> {
U getId();
}
OR
public class RepoElement<U> {
private U Id;
public RepoElement() {}
public RepoElement(U id) {
Id = id;
}
public U getId() {
return Id;
}
public void setId(U id) {
Id = id;
}
}
2- Make Department inherit from the interface OR class
public class Department implements RepoElement<Long> {
(...)
public Long getId() {
return Id;
}
(...)
}
OR
public class Department extends RepoElement<Long> {
private String Name;
private String Location;
public Department() {
super();
}
public Department(long id, String name, String location) {
super(id);
Name = name;
Location = location;
}
}
3- Use it directly in the Repo class (and remove exceptions)
public class Repo<T extends RepoElement<U>, U> {
(...)
public T get(U id) {
for (T ele : list) {
if (ele.getId().equals(id)) {
return ele;
}
}
return null;
}
public void delete(U id) {
list.remove(get(id));
}
(...)
}
As a last suggestion, you could use a Map instead of a List in the Repo class, and get rid of any search complexity/optimizations:
public class Repo<T extends RepoElement<U>, U> {
Map<U, T> map = new HashMap<U, T>();
public Collection<T> getAll() {
return map.values();
}
public void insert(T obj) {
map.put(obj.getId(), obj);
}
public T get(U id) {
return map.get(id);
}
public void delete(U id) {
map.remove(id);
}
}
You need to invoke the getId() method so that it will return the id to perform comparison correctly:
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
public class Repo<T, U> {
List<T> list = new ArrayList<T>();
public List<T> getAll() {
return list;
}
public void insert(T obj) {
list.add(obj);
}
public T get(U id) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
for (T ele : list) {
if (ele.getClass().getMethod("getId").invoke(ele).equals(id)) {
return ele;
}
}
return null;
}
public void delete(U id) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
list.remove(get(id));
}
}
Scenario: A data object which persists in the DB table. There are some old entries in the table. Now I have to apply encryption to new further entries in the table. So I add a new column which has the field encrypted set to False by default to check if the values are encrypted.
Problem: I want to write an annotation to encrypt the fields in the data model(POJO) before persisting and decrypt on getter() calls only if it is encrypted.
Context:
The user model.
public class UserData {
#Id
#Column(name = "ID", length = 36)
private String id;
#Column(name = "IS_ENCRYPTED")
private boolean isEncrypted;
#Column(name = "NAME")
#Convert(converter = EncryptionConverter.class)
private String name;
// more fields ....
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
// more similar getter and setters
}
The encryption class that i have written.
#Converter
public class EncryptionConverter implements AttributeConverter<String, String>{
private final String secretKey= "someSecret";
UserData Data = new UserData();
#Override
public String convertToDatabaseColumn(String str) {
if(!isNullOrBlank(str))
return AesEncrypt.encrypt(str, secretKey);
return str;
}
#Override
public String convertToEntityAttribute(String encrypedStr) {
if(!isNullOrBlank(encrypedStr) && Data.isEncrypted)
return AesEncrypt.decrypt(encrypedStr, secretKey);
return encrypedStr;
}
}
This class is inside the model class. (can move outside, but how to pass isencrypted flag to annotation)
How can I do this, is my approach correct?
Edit: there are multiple fields which are to be encrypted/decrypted not just name.
You can create the encryption behaviour in another configuration class, say EncryptedPropertyConfig, in this you can create a bean, EncryptablePropertyResolver from jasypt-spring-boot
#EnableAutoConfiguration
public class EncryptedPropertyConfig {
public EncryptedPropertyConfig() {
}
#Bean
public EncryptablePropertyResolver encryptablePropertyResolver() {
EncryptablePropertyResolver r = new MyPropertyPlaceholderConfigurer();
return r;
}
}
public final class MyPropertyPlaceholderConfigurer implements EncryptablePropertyResolver {
private StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
private EnvironmentStringPBEConfig envConfig = new EnvironmentStringPBEConfig();
public MyPropertyPlaceholderConfigurer() {
// set the encryption key and config
}
public String resolvePropertyValue(String passedValue) {
if (!PropertyValueEncryptionUtils.isEncryptedValue(passedValue)) {
return passedValue;
} else {
String returnValue = "";
try {
returnValue = PropertyValueEncryptionUtils.decrypt(passedValue, this.encryptor);
return returnValue;
} catch (Exception var4) {
throw new RuntimeException("Error in decryption of property value:" + passedValue, var4);
}
}
}
}
I suggest alternative solution using Entity Listeners
import javax.persistence.PostLoad;
import javax.persistence.PreUpdate;
public class UserData {
private final String secretKey= "someSecret";
// ...
#PreUpdate
private void onUpdate() {
// triggered before saving entity to DB (both create & update)
if(!isNullOrBlank(name)) {
name = AesEncrypt.encrypt(name, secretKey);
}
}
#PostLoad
private void onLoad() {
// triggered after entity is fetched from Entity Provider
if (!isNullOrBlank(name) && isEncrypted) {
name = AesEncrypt.decrypt(name, secretKey);
}
}
}
Instead of using JPA AttributeConverter you can implement hibernate user type in this way:
import java.util.Objects;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.type.StringType;
import org.hibernate.usertype.UserType;
public class CustomNameType implements UserType
{
private String secretKey = "someSecret";
public CustomNameType()
{
}
#Override
public Object deepCopy(Object value) throws HibernateException
{
if (null == value) return null;
return ((CustomName) value).clone();
}
#Override
public Object assemble(Serializable cached, Object owner) throws HibernateException
{
return cached;
}
#Override
public Serializable disassemble(Object value) throws HibernateException
{
return (Serializable) value;
}
#Override
public Object replace(Object original, Object target, Object owner) throws HibernateException
{
return original;
}
#Override
public boolean equals(Object one, Object two) throws HibernateException
{
return Objects.equals(one, two);
}
#Override
public int hashCode(Object obj) throws HibernateException
{
return Objects.hashCode(obj);
}
#Override
public boolean isMutable()
{
return true;
}
#Override
public Object nullSafeGet(ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException
{
boolean isEncrypted = rs.getBoolean(0); // IS_ENCRYPTED
String name = rs.getString(1); // NAME
if (isEncrypted) {
name = AesEncrypt.decrypt(name, secretKey);
}
return new CustomName(isEncrypted, name);
}
#Override
public void nullSafeSet(PreparedStatement statement, Object value, int index, SharedSessionContractImplementor session)
throws HibernateException, SQLException
{
CustomName customName = (CustomName) value;
String name = customName.getName();
if (customName.isEncrypted()) {
name = AesEncrypt.encrypt(name, secretKey);
}
statement.setBoolean(0, customName.isEncrypted());
statement.setString(1, name);
}
#Override
public Class<?> returnedClass()
{
return CustomName.class;
}
#Override
public int[] sqlTypes()
{
// I do not know the types of your IS_ENCRYPTED and NAME fields
// So, this place maybe require correction
int[] types = {BooleanType.INSTANCE.sqlType(), StringType.INSTANCE.sqlType()};
return types;
}
}
where CustomName is:
public class CustomName implements Serializable, Cloneable
{
private boolean isEncrypted;
private String name;
public CustomName(boolean isEncrypted, String name)
{
this.isEncrypted = isEncrypted;
this.name = name;
}
// getters , equals, hashCode ...
#Override
public CustomName clone()
{
return new CustomName(isEncrypted, name);
}
}
and then use it:
import org.hibernate.annotations.Type;
import org.hibernate.annotations.Columns;
#Entity
public class UserData {
#Type(type = "com.your.CustomNameType")
#Columns(columns = {
#Column(name = "IS_ENCRYPTED"),
#Column(name = "NAME")
})
private CustomName name;
}
Say I have class AccountPojo and GetAccountPojo with its setter and getter methods as below.
public class AccountPojo {
private String dataList;
private String dataSet;
public String getDataList() {
return dataList;
}
public void setDataList(String dataList) {
this.dataList = dataList;
}
public String getDataSet() {
return dataSet;
}
public void setDataSet(String dataSet) {
this.dataSet = dataSet;
}
}
public class GetAccountsPojo {
private String accountId;
private int noOfAccounts;
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public int getNoOfAccounts() {
return noOfAccounts;
}
public void setNoOfAccounts(int noOfAccounts) {
this.noOfAccounts = noOfAccounts;
}
}
Now I have class Test as below
public Class Test {
public static void main(String[] args) {
Class cls = Class.forName("com.org.temp."+ClassName); // ClassName(AccountPojo/GetAccountPojo) here I know already which class is getting called.
Object clsInstance = (Object) cls.newInstance();
System.out.println("The cls is==" + cls+" and classInstance is=="+clsInstance);
// Here I want to access getter and setter methods of AccountPojo and GetAcoountPojo dynamically, no hard coding
}
}
Have you tried getting all the methods of the invoked class and filtering out only the getter methods by name and invoking them?
Method[] methods = cls.getClass().getDeclaredMethods();
for (Method m: methods) {
if(m.getName().startsWith("get")) {
m.invoke(clsInstance);
}
}
This solves our half problem, as getters are invoked without any arguments. But if you need to invoke a setter method you need to specify arguments. Ex, To invoke a setter which accepts string argument method as below:
m.invoke(clsInstance, "some string argument");
One solution to could be make all the setters accept an object type value and typecast them while assigning it to actual class variables.
Now your pojo classes will look as below:
public class AccountPojo {
private String dataList;
private String dataSet;
public String getDataList() {
return dataList;
}
public void setDataList(Object dataList) {
this.dataList = (String) dataList;
}
public String getDataSet() {
return dataSet;
}
public void setDataSet(Object dataSet) {
this.dataSet = (String)dataSet;
}
}
public class GetAccountsPojo {
private String accountId;
private int noOfAccounts;
public String getAccountId() {
return accountId;
}
public void setAccountId(Object accountId) {
this.accountId = (String) accountId;
}
public int getNoOfAccounts() {
return noOfAccounts;
}
public void setNoOfAccounts(Object noOfAccounts) {
this.noOfAccounts = (int) noOfAccounts;
}
}
Add below code to your main method:
for (Method m: methods) {
if(m.getName().startsWith("get")) {
m.invoke(clsInstance);
}
if(m.getName().startsWith("set")) {
m.invoke(clsInstance, "any argument to be passed here");
}
}
Don't use raw class. If you know which class is called already, use typed class.
try {
AccountPojo obj = AccountPojo.class.newInstance();
Method setDataList = AccountPojo.class.getMethod("setDataList");
setDataList.setAccessible(true); // This is important if you want to access protected or private method. For public method you can skip
setDataList.invoke(obj, "123");
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
I am working with a java example using annotations, I created a simple POJO (java bean) using annotations to its attributes. I want to have the ability to create new objects of this type and retrieve the values of its attributes using the annotations created.
My POJO :
import java.io.Serializable;
import annotations.BusinessObject;
import annotations.BusinessObjectAttribute;
import annotations.BusinessObjectName;
import annotations.BusinessObjectPolicy;
import annotations.BusinessObjectRevision;
import annotations.BusinessObjectVault;
#BusinessObject
public class IndusTask implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
// Mandatory to create new object !
#BusinessObjectName
private String taskName;
#BusinessObjectRevision
private String taskRevision;
#BusinessObjectVault
private String vault;
// Mandatory to invoke iTask.create(context, policy) in Database
#BusinessObjectPolicy
private String policy;
//Specific attributes
#BusinessObjectAttribute
private String taskDescription;
#BusinessObjectAttribute
private String creationDate;
#BusinessObjectAttribute
private Integer weight;
public IndusTask() {
}
public IndusTask(String taskName, String taskRevision, String vault, String policy, String taskDescription,
String creationDate, Integer weight) {
super();
this.taskName = taskName;
this.taskRevision = taskRevision;
this.vault = vault;
this.policy = policy;
this.taskDescription = taskDescription;
this.creationDate = creationDate;
this.weight = weight;
}
public String getTaskName() {
return taskName;
}
public void setTaskName(String taskName) {
this.taskName = taskName;
}
public String getTaskRevision() {
return taskRevision;
}
public void setTaskRevision(String taskRevision) {
this.taskRevision = taskRevision;
}
public String getVault() {
return vault;
}
public void setVault(String vault) {
this.vault = vault;
}
public String getTaskDescription() {
return taskDescription;
}
public void setTaskDescription(String taskDescription) {
this.taskDescription = taskDescription;
}
public String getCreationDate() {
return this.creationDate;
}
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public String getPolicy() {
return policy;
}
public void setPolicy(String policy) {
this.policy = policy;
}
}
Example of attributes' declaration:
*Business Object Type declaration
package annotations;
import java.lang.annotation.*;
//#Target(ElementType.TYPE)
#Retention(RetentionPolicy.RUNTIME)
public #interface BusinessObject {
}
*Business Object Name Attribute:
package annotations;
import java.lang.annotation.*;
//#Target(ElementType.FIELD)
#Retention(RetentionPolicy.RUNTIME)
public #interface BusinessObjectName {
}
I Created a main to test if all the annotations are detected:
public class MainImpl {
public static void main(String[] args) {
// TODO Auto-generated method stub
IndusTask myTask = new IndusTask("mytstTask", "001", "eService Production", "TstTask Process",
"myTstTask Description", "2018/02/16#15:30:10:GMT", 200);
System.out.println(myTask.getClass().getAnnotations().length);
}
}
Output is displaying 1 ! so only the first annotation is detected !
I was told also that the object attributes values can be accessed using these annotation (something similar to) :
object.getClass().getAnnotations()
How can i do ?
You need to iterate through the fields, get their annotations and set the value wherever the annotation matches (it can match multiple fields):
#Retention(RetentionPolicy.RUNTIME)
public #interface Field1 {}
#Retention(RetentionPolicy.RUNTIME)
public #interface Field2 {}
public static class UnderTest {
#Field1
private String field1;
#Field2
private int field2;
public UnderTest(String field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
#Override
public String toString() {
return field1 + "=" + field2;
}
}
public static void setter(Object obj, Class<? extends Annotation> fieldAnnotation, Object fieldValue) throws IllegalAccessException {
for (Field field: obj.getClass().getDeclaredFields()) {
for (Annotation annot: field.getDeclaredAnnotations()) {
if (annot.annotationType().isAssignableFrom(fieldAnnotation)) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
field.set(obj, fieldValue);
}
}
}
}
public static void main(String[] argv) throws IllegalAccessException {
UnderTest underTest = new UnderTest("A", 1);
System.out.println(underTest);
setter(underTest, Field1.class, "B");
setter(underTest, Field2.class, 2);
System.out.println(underTest);
}
Running this prints
A=1
B=2
Sounds like you're after the annotations on the fields too?
E.g. for the first private field:
myTask.getClass().getDeclaredFields()[0].getAnnotations()
Note depending how you're accessing a private field, you will sometimes also need to first ensure it is accessible:
...getDeclaredFields()[0].setAccessible(true);
[edit]
The values are reachable too from the fields. A basic worked example:
for (Field f : myTask.getClass().getDeclaredFields()) {
f.setAccessible(true);
System.out.println(f.getName() + "=" + f.get(myTask));
System.out.println(" annotations=" + java.util.Arrays.toString(f.getAnnotations()));
}
I have error:
com.google.gwt.user.client.rpc.SerializationException: Type 'ru.xxx.empeditor.client.Dept$$EnhancerByCGLIB$$2f6af516' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = ru.xxx.empeditor.client.Dept#e53d4e
Why this class not serializable?
package ru.xxx.empeditor.client;
import java.util.HashSet;
import java.util.Set;
import com.google.gwt.user.client.rpc.IsSerializable;
/**
* Dept generated by hbm2java
*/
public class Dept implements IsSerializable {
private byte deptno;
private String dname;
private String loc;
private Set<Emp> emps = new HashSet<Emp>(0);
public Dept() {
}
public Dept(byte deptno) {
this.deptno = deptno;
}
public Dept(byte deptno, String dname, String loc, Set<Emp> emps) {
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
this.emps = emps;
}
public byte getDeptno() {
return this.deptno;
}
public void setDeptno(byte deptno) {
this.deptno = deptno;
}
public String getDname() {
return this.dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return this.loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Set<Emp> getEmps() {
return this.emps;
}
public void setEmps(Set<Emp> emps) {
this.emps = emps;
}
}
Check if the class Emp is serialiable.
Another potential issue (since you are using Hibernate - noticed the auto-generated comment) could be because of Proxies that modify your bean's byte code, as a result of which GWT fails to serialize it. As mentioned here - http://code.google.com/webtoolkit/articles/using_gwt_with_hibernate.html