Non-serializable field in serializable class (transient keyword) - java

I have a serializable class that extends Servlet
public class FileDownload extends HttpServlet{
#SuppressWarnings("compatibility:6754389671327954013")
private static final long serialVersionUID = 1L;
private ResultSet rset;
......
}
My Question is:
Is the rset object automatically converted as transient at compile- or run-time? or do I have to mark it explicitly as transient? (That is a warning brought up from my IDE JDeveloper).

No, the field is not neglected by serialization - you'll get a java.io.NotSerializableException if you try to serialize an instance of FileDownload. Mark it transient. Btw, what is a ResultSet doing as a field in a Servlet? This is not thread-safe. ResultSets should be local variables only, in any context.

You have to call transient your own.But you cannot serialize an object unless it implements Serializable interface.ResultSet is such kind of object.

Related

Getting spotbug issue type SE_TRANSIENT_FIELD_NOT_RESTORED

I have one listner class 'A', which implements interface 'B' and 'B' extends Serializable class.
Now in class 'A',
If I declare logger as transient as below:
private final transient Logger logger = LoggerFactory.getLogger(getClass());
then spotbug reports error as below:
logger is transient but isn't set by deserialization
If I declare logger as non-transient
private final Logger logger = LoggerFactory.getLogger(getClass());
m getting below error:
Make "logger" transient or serializable.
how to resolve this problem ?
The problem is that deserialization doesn't follow the normal rules of object initialization, so the transient field will not be populated, and instead it will be null.
The simplest solution is to make the field static, so it isn't a member of an instance. However, if you have a reason to make it an instance field, for example if you have a lot of subclasses, and you want your logging to be able to identify the actual class, then you need to make sure the transient field is populated when it is deserialized.
This can be done with either readResolve() or readObject(ObjectInputStream). For example:
private Object readResolve() throws ObjectStreamException {
logger = LoggerFactory.getLogger(getClass());
return this;
}
or
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject()
logger = LoggerFactory.getLogger(getClass())
}
In both cases, the field logger can no longer be final.

How can transient variables be used in a class that implements Parcelable?

I need to understand if a transient variable inside a class that implements Parcelable interface should be read from the parcel in modelClass(Parcel parcel) method or written to the parcel in writeToParcel(Parcel parcel,int i) . Can anyone provide me with a class implementation with a transient variable in it. Thank you.
The "transient"-keyword has no effect on parcelable objects. There is no automation in reading and writing the fields in a parcelable object, so there is no ready made code that would take it into account. Any possible choice of special processing for transient fields is completely up to the person designing the class.
Specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.3) says "Variables may be marked transient to indicate that they are not part of the persistent state of an object" so if you really want to go by the book you should not write them. But, as I said, since the reading and writing is done mechanically inside the class, the transient keyword doesn't make much sense.
class Employee implements Serializable {
private String firstName;
private String lastName;
private transient String confidentialInfo;
//Setters and Getters
}
You can simply add transient keyword before data type while declaring variable.
class Parcel implements Parcelable{
private Integer checkinId;
private transient String someCode;
//// some methods
}
interface Parcelable implements{
// some methods
}

jackson-databind "object is not an instance of declaring class"

I have been upgrading to a later version of jackson (i.e. from org.codehaus... to com.fasterxml...) and suddenly I am facing many weird errors. After hours of trying and adjusting I still cant get it to work so I am asking you guys if you can help me.
I have the following method:
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("getTerminalsByIdAndLocation")
List<SearchResultDto> getTerminalsByIdAndLocation(#QueryParam("location") String location, #QueryParam("id") Integer id) throws BusinessException;
and that functions implementation just does a lookup in a repository.
The SearchResultDto looks like this:
#JsonIgnoreProperties(ignoreUnknown = true)
public class SearchResultDto implements Serializable {
private static final long serialVersionUID = 1L;
private TerminalId terminalId;
private Integer location;
private String streetNumber;
private String postalcoldeCity;
private Status status;
// getters and setters with no annotation or so
}
When I am now calling my method I am getting the following error:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: object is not an instance of declaring class (through reference chain: java.util.ArrayList[0]-><long package>.SearchResultDto["terminalId"])
After a lot of trying I thought I will just remove the terminalId and then it changes to:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: object is not an instance of declaring class (through reference chain: java.util.ArrayList[0]-><long package>AtmSearchResultDto["location"])
I am clueless, what is wrong here?
EDIT
I also tried using #JsonIgnore on everything except String streetNumber but then the same exception happens just for streetNumber
Long story short: I messed up my class path and there were two class loaders, the implementation of the REST method called a repository from the database module from where it got the instance from a different class loader. After adjusting my maven scopes and import types it is now working!
I had a similar issue for me the problem was that one of my POJOs was final. Removing the final keyword did the trick.
public final class AccessControlMap extends HashMap<Permission, Set<AccessType>>
//Before
public final class AccessType {
//After
public class AccessType {

Serializable by extending with empty constructor?

TLDR: Is there a way to force to a subclass to have an empty constructor when the super does not?
I need to be to initialize a non-serializable class, TravelTimeDataArray, from a serialized data container. The TravelTimeDataArray cannot be serialized because it does not implement the Serializable interface, lacks an empty constructor, and uses a non-serializable field of type Link.
public class TravelTimeDataArray implements TravelTimeData {
private final double[] timeSum;
private final int[] timeCnt;
private final double[] travelTimes;
private final Link link; //I'm not serializable
public TravelTimeDataArray(final Link link, final int numSlots) {
this.timeSum = new double[numSlots];
this.timeCnt = new int[numSlots];
this.travelTimes = new double[numSlots];
this.link = link;
resetTravelTimes();
}
//getters and setters
}
My first thought was to extend this as a serializable class. Instead of using a Link, I can use a serializable String of it's ID attribute and add the empty constructor.
public class SerialTravelTimeDataArray extends TravelTimeDataArray implements java.io.Serializable{
private final String linkId = null; // I am serializable
public SerialTravelTimeDataArray(){ }
public SerialTravelTimeDataArray(TravelTimeDataArray ttDA){
// intialize me using ttDA's data
}
// Methods to serialize the fields.
// Methods to populate super's fields from the deserialized data containers
}
Since the super does not have an empty constructor, I get an error with the subclass's empty constructor. Is there a way to force to a subclass to have an empty constructor when the super does not?
According to The Serializable Interface:
A Serializable class must do the following:
Implement the java.io.Serializable interface
Identify the fields that should be serializable (Use the serialPersistentFields member to explicitly declare them serializable
or use the transient keyword to denote nonserializable fields.)
Have access to the no-arg constructor of its first nonserializable superclass
A no-arg constructor of a object's first nonserializable superclass is need to have access because it will be called while deserializing the object. Otherwise, an exception will be thrown. Note that serializing a object do not call its superclass's default constructor and no exception will be thrown.
If extending a class is not a must, you can consider using encapsulation like follows:
public class Foo implements Serializable {
private final double[] timeSum;
private final int[] timeCnt;
private final double[] travelTimes;
private final String linkId;
private final transient TravelTimeDataArray ttDA;
public Foo(TravelTimeDataArray ttDA) {
this.ttDA = ttDA;
this.timeSum = ttDA.getTimeSum();
this.timeCnt = ttDA.getTimeCnt();
this.travelTimes = ttDA.getTravelTimes();
this.linkId = ttDA.getLink().getId();
}
// Methods
}
If you do not need to access TravelTimeDataArray in your class, you can skip the field transient TravelTimeDataArray ttDA. Hope this can help.

JPA generic field

Is it possible to persist a generic field?
I have this property on an Entity class
...
private T payload;
...
T extends EventMessagePayload
and
public interface StringPayload extends EventMessagePayload{
String getPayload();
}
In my application i persist the field only when is of String type and during the save operation all works great.
When I read the object instead JPA try to create a String object but instead is a StringPaylod. Is there a way to intercept the creation and handle the object marshalling?
JPA itself does not allow this, but your JPA implementation might allow it. We once did this with Hibernate, and it boilds down to implement your own EntityTuplizer (and a HibernateInterceptor to map your objects back to HibernateEntities).
We can. if the T implements Serializable
#Entity
public class IgsSubject extends BasicObject implements Serializable{
private static final long serialVersionUID = -5387429446192609471L;

Categories