1

Is there anything wrong with declaring collection transient? transient Map<String, Car> cars = new HashMap<>() is declared in Ownerinstance that is serialized, but the Car class is not serialized.

When program runs for the first time Owner instance it creates Car and insert it into collection Cars, however when running program for second time, Owner is deserialized, it correctly creates Car instance but when adding to collection cars.put(key, object) it causes NullPointerException. Also only when running after deserialization cars.containsKey(regNumIn) causes exception instead of giving true or false. It seems that on second run after Owner is recreated the new hashMap is created.

Does it have to do anything with hasCode() and equals()? I havent declared those, and if they are automatically declared by Netbeans IDE, the program doesnt work at all.

  • The `transient` keyword in Java is used to indicate that a field should not be serialized. So after deserialization you have `null` instead of your map – ByeBye Jun 16 '17 at 10:45

3 Answers3

2

Your problem has nothing at all to do with Collections. "transient" tells Java that you do not want to store the fields value, so when you reload the stored object, transient fields are set to null (or 0, or other respective default values). Therefore, in your example code of cars.put(key, object), you are essentially attempting to do null.put(key, object).

containsKey of course fails for the same reason - you are attempting to call it on something that is null.

If you don't want to serialize your collection, you will have to do something like cars = new HashMap<>() after deserializing it.

That means the problem is also unrelated to equals and hashCode, however the information that your program 'breaks' when you have Netbeans generate them suggests that you may have other issues. Good information about equals and hashCode can be found in this related SO question:

What issues should be considered when overriding equals and hashCode in Java?

Torque
  • 3,319
  • 2
  • 27
  • 39
1

Java does not call the default constructor when deserializing the object. Therefore, your code

transient Map<String, Car> cars = new HashMap<>();

will not be executed.

To accomplish this, you can override the readObject method of your class:

public class ... implements Serializable {
    ...
    private transient Map<String, Car> cars = new HashMap<>();
    ...
    private void readObject(ObjectInputStream stream)
              throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        // Important! recreate transient field cars as empty HashMap
        this.cars = new HashMap<>();
    }
    ...
}
Torsten Fehre
  • 567
  • 2
  • 7
-1

I removed transient statement and I implemented Serializable interface in a Car class, and it works. I think the problem was that collection being transient was not saved after first run, and in the second run when Owner object was deserialized, the non-argument constructor is not called, therefore the new cars collection in that constructor was not created. So in the second run it was attempted to add car object to non existing collection.