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()));
}
Related
How do I get Jackson to treat 'name' as if it had a #JsonProperty annotation?
public class SimpleClass {
private String name;
private String doNotSerialize;
public SimpleClass( #JsonProperty("name") String name ) {
this.name = name;
}
public String getName() {
return name;
}
public int getSum() {
return 1+1;
}
}
The way it is now, I get an error, Unrecognized field "sum", because it treats every getter as a serializable property.
If I add a class annotation:
#JsonAutoDetect( getterVisibility = JsonAutoDetect.Visibility.NONE )
I get an empty string when serializing. I was hoping that Jackson would see the #JsonProperty on the constructor parameter and figure it out.
If I change the class annotation to:
#JsonAutoDetect( getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.ANY )
Then I get the 'doNotSerialize' field included.
If I set a #JsonCreator on the constructor, and change my autodetect, I still get a blank string:
#JsonAutoDetect( getterVisibility = JsonAutoDetect.Visibility.NONE, fieldVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.ANY )
public class SimpleClass {
private String name;
private String doNotSerialize;
#JsonCreator
public SimpleClass( #JsonProperty("name") String name ) {
this.name = name;
}
public String getName() {
return name;
}
public int getSum() {
return 1+1;
}
}
What I'm hoping is that somehow I can tell Jackson to treat all the constructor parameters as serializable fields, and all other fields / setters as non-serializable.
You can use a filter to only serialise getters which have a matching field, e.g.
package org.example;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.PropertyWriter;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import java.io.IOException;
import java.io.StringWriter;
public class App {
#JsonFilter("test")
public static class SimpleClass {
private String name;
private String doNotSerialize;
public SimpleClass(String name ) {
this.name = name;
}
public String getName() {
return name;
}
public int getSum() {
return 1+1;
}
}
public static void main( String[] args ) throws IOException {
SimpleFilterProvider filterProvider = new SimpleFilterProvider();
filterProvider.addFilter("test", new SimpleBeanPropertyFilter() {
#Override
protected boolean include(BeanPropertyWriter writer) {
return super.include(writer);
}
#Override
protected boolean include(PropertyWriter writer) {
String name = writer.getName();
Class clazz = writer.getMember().getDeclaringClass();
try {
clazz.getDeclaredField(name);
return super.include(writer);
} catch (NoSuchFieldException e) {
// ignore
return false;
}
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.setFilterProvider(filterProvider);
StringWriter sw = new StringWriter();
mapper.createGenerator(sw).writeObject(new SimpleClass("foo"));
System.out.println(sw.toString());
}
}
I don't know your full requirements, but this should be a start.
I haven't tried to do what you actually, asked, that is, look at constructor parameters, but that should be possible too.
If you want "sum" to be included in the serializad json but want to ignore it when deserializing you can do:
#JsonIgnoreProperties(ignoreUnknown=true)
public class SimpleClass {
// properties/getters
public int getSum() { return 1+1; }
}
If you want to remove "sum" entirely from the json you can do
#JsonIgnoreProperties({"sum"})
public class SimpleClass {
// properties/getters
public int getSum() { return 1+1; }
}
or
public class SimpleClass {
// properties/getters
#JsonIgnore
public int getSum() { return 1+1; }
}
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;
}
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));
I create an java class:
public class ReturnObj {
private String returncode;
private String returndesc;
private Pkg pkg;
public String getReturncode() {
return returncode;
}
public void setReturncode(String returncode) {
this.returncode = returncode;
}
public String getReturndesc() {
return returndesc;
}
public void setReturndesc(String returndesc) {
this.returndesc = returndesc;
}
}
and other class:
public class Pkg {
private String packagecode;
private String cycle;
private String price;
private String desc;
public String getPackagecode() {
return packagecode;
}
public void setPackagecode(String packagecode) {
this.packagecode = packagecode;
}
public String getCycle() {
return cycle;
}
public void setCycle(String cycle) {
this.cycle = cycle;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
And I Want to convert object ReturnObj to this XML
<return>
<returncode>1</returncode>
<returndesc>DANG_KY_THANH_CONG</returndesc>
<package>
<packagecode>BD30</packagecode>
<cycle>1</cycle>
<price>15000</price>
<desc> BD30</desc>
</package>
</return>
So how do I serialize an attribute pkg to package in XML? Because Java doesn't allow to name variable as an keyword anh package is an keyword in Java !
You can use JAXB marshling in your class it will convert the object to XML, here is link to help you JAXB Marshling
Try xstream
XStream xstream = new XStream();
xstream.alias("package", Pkg.class);
String xml = xstream.toXML(myReturnObj);
You can use JAXB API that comes with java for converting java object to XML.
Below is the code that will solve your requirement.
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "return")
public class ReturnObj {
private String returncode;
private String returndesc;
private Pkg pkg;
public Pkg getPkg() {
return pkg;
}
#XmlElement(name = "package")
public void setPkg(Pkg pkg) {
this.pkg = pkg;
}
public String getReturncode() {
return returncode;
}
#XmlElement(name = "returncode")
public void setReturncode(String returncode) {
this.returncode = returncode;
}
public String getReturndesc() {
return returndesc;
}
#XmlElement(name = "returndesc")
public void setReturndesc(String returndesc) {
this.returndesc = returndesc;
}
}
#XmlRootElement
public class Pkg {
private String packagecode;
private String cycle;
private String price;
private String desc;
public String getPackagecode() {
return packagecode;
}
#XmlElement(name="packagecode")
public void setPackagecode(String packagecode) {
this.packagecode = packagecode;
}
public String getCycle() {
return cycle;
}
#XmlElement(name="cycle")
public void setCycle(String cycle) {
this.cycle = cycle;
}
public String getPrice() {
return price;
}
#XmlElement(name="price")
public void setPrice(String price) {
this.price = price;
}
public String getDesc() {
return desc;
}
#XmlElement
public void setDesc(String desc) {
this.desc = desc;
}
}
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
private static final String FILE_NAME = "C:\\ru\\jaxb-returnObj.xml";
public static void main(String[] args) {
ReturnObj returnObj = new ReturnObj();
returnObj.setReturncode("1");
returnObj.setReturndesc("DANG_KY_THANH_CONG");
Pkg pkg = new Pkg();
pkg.setCycle("1");
pkg.setPrice("15000");
pkg.setDesc("BD30");
returnObj.setPkg(pkg);
jaxbObjectToXML(returnObj);
}
private static void jaxbObjectToXML(ReturnObj emp) {
try {
JAXBContext context = JAXBContext.newInstance(ReturnObj.class);
Marshaller m = context.createMarshaller();
// for pretty-print XML in JAXB
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// Write to System.out, this will print the xml on console
m.marshal(emp, System.out);
// Write to File
m.marshal(emp, new File(FILE_NAME));
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Explanation:
#XmlRootElement: This is a must have annotation for the Object to be used in JAXB. It defines the root element for the XML content.
#XmlElement: This will create the element. If you want to give some other name to the xml element when converting java object to xml then you can pass name attribute to the #XmlElement Example:
#XmlElement(name = "package")
Execute above code to see the desired output.
Happy Coding.
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