NullPointer while creating a class with attribute of another class - java

I work on a project that stores my Items , Persons and action when I Borrow some Item to some Person
This project is based on a YouTube tutorial for classical library of books.
I'm sorry for I will post some more code because I want to give some idea how I'm doing it. I personally think that there is a problem with how I get the instances of ItemClass or PersonClass. Or something with inheritance around BorrowClass.
Now first two Methods in BorrowClass works okay, creating items and persons and adding to the lists, but when I try to create new BorrowClass containing and instance of items or persons it throws nullPointer, yet through debug I was able to see borrowed in variables and everything seemed to be not null or does the red squares means problem ?
I create ItemClass
public class ItemClass implements Serializable {
private static final long serialVersionUID = 1L;
private int isbn;
private String title, author;
private String otherInfo;
public ItemClass(String title,String otherInfo, String author,int isbn) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.otherInfo = otherInfo;
}
Then PersonClass
public class PersonClass implements Serializable {
private static final long serialVersionUID = 1L;
private int telephone;
private String name, surename, email;
public PersonClass(String name,String surename, int telephone,String email) {
this.name = name;
this.surename = surename;
this.telephone = telephone;
this.email = email;
}
Then BorrowCLass
public class BorrowClass implements Serializable {
private static final long serialVersionUID = 1L;
private ItemClass item;
private PersonClass person;
private Date borrowDate;
private Date expireDate;
public BorrowClass(ItemClass item, PersonClass person, Date borrowDate,
Date expireDate) {
this.item = item;
this.person = person;
this.borrowDate = borrowDate;
this.expireDate = expireDate;
}
Now All above I handle in Library class
public class Library extends Object implements Serializable {
private static final long serialVersionUID = 1L;
private List<ItemClass> listOfItems;
private List<PersonClass> listOfPersons;
private List<BorrowClass> listOfBorrowed;
public Library() {
listOfItems = new ArrayList<ItemClass>();
listOfPersons = new ArrayList<PersonClass>();
listOfBorrowed = new ArrayList<BorrowClass>();
}
public void addItemtoItemsCollection(ItemClass item) {
listOfItems.add(item);
}
public void addPersontoPersonCollection(PersonClass person) {
listOfPersons.add(person);
}
public void addBorrow(BorrowClass borrowed) {
listOfBorrowed.add(borrowed);
}
Also would be nice if someone could explain the meaning of
private static final long serialVersionUID = 1L;
because in the video I didn't get it and I would like to know.
Thanks for any answer.

About serialVersionUID :
So... basically at some point you may want to serialize your objects and save them somewhere ( like in a file or in db), so that you can deserialize them later. Now, serialVersionUID field is used to know, if you are using the same class definition as that was being used when this object was created an serialized.
So... whenever you make a change to some class that is serializable, you increase the serialVersionUID by 1 so that any seiralized object of old class version is not wrongly deserialized using the current class version.

Ladies and gentleman I humbly apologise for my stupidity. I have function load from file and I was loading an OLD library file where list borrow was still not existing there fore no list to add to. And here I have the nullPointer. I was stuck on this for a while but only for my stupidity :) Thanks all for help. You can close the topic

Related

To define an object in a constructor in Serializable class

I have a JSON response like below image, and I have made a serializable class named as Project
In the image, I have two objects (emergency_contact, and secondary_owner) inside my an array of one object. I'm trying to figure out whether what to do in order to define the object, since I want that details to be present inside my constructor.
I have done this so far:
public class Project implements Serializable {
public int id;
public String name;
public String additional_information;
//Now what to do Emergency contact
public Project(int id, String name, String additional_information){
}
}
I have thought of doing this, public EmergencyContact emergency = new EmergencyContact(param1, param2).
And make a new class named as EmergencyContact, and do a getter and setter for the params. But after doing this, I'm still confused, how would I define it my constructor?
I know I'm close, but I need some help on that.
Sure. You need to have a:
public class EmergencyContact implements Serializable {
public String name;
public String number;
public EmergencyContact(String name, String number){
// assign fields
}
}
and one for the owner:
public class EmergencyOwner implements Serializable {
public String name;
public String number;
public EmergencyOwner(String name, String number){
// assign the fields
}
}
then in your Project class you can add fields of these classes:
public class Project implements Serializable {
public int id;
public String name;
public String additional_information;
public EmergencyContact emergency_contact;
public EmergencyOwner emergency_owner;
public Project(int id, String name, String additional_information, EmergencyContact emergency_contact, EmergencyOwner emergency_owner){
// assign the fields here as well
}
}
that's it. If that's an answer to the question consider to delete this question as it is a duplicated on a 100% :)
As a note, to be correctly from the point of clean code parameters, the fields should be private in a class, and use setters / getters to set/retrieve values from/to those fields.
public class Project implements Serializable {
private int id;
private String name;
private String additional_information;
private EmergencyContact emergency_contact;
private SecondaryOwner secondary_owner;
public Project(int id, String name, String additional_information, EmergencyContact emergencyContact, SecondaryOwner secondaryOwner){
this.id = id;
this.name = name;
this.additional_information = additional_information;
this.emergency_contact = emergencyContact;
this.secondary_owner = secondaryOwner;
}
}
You will define the other two classes the same way. Now, you are probably confused about the constructor of EmergencyContact & SecondaryOwner classes.. You can device both default constructors (without parameters) and a custom one(with parameters to it, just as the one above). If you use the default constructor, make sure to set values to the fields in the object, as following :
EmergencyContact emergencyContact = new EmergencyContact();
emergencyContact.setName("the name");
emergencyContact.setNumber("a number");
then you can use this object in the constructor of Project class
I hope it was clear enough, for any other clarifications feel free to ask.
Happy coding <3

Hibernate #PreUpdate: check what has been changed

Question: How to check which fields has been changed inside method annotated with #PreUpdate?
OPTIONAL: if the answer to the question above is "It's impossible, than maybe there are another ways to solve my problem"
I want automatically update modified Tourist's field each time we change something in it.
Except the situation when we modify only location. Means if we change location only - it should be persisted, but modified mustn't be changed.
Already present code:
#Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
#PreUpdate
public void preUpdate() {
modified = new Date(); //PROBLEM : change modified even if only location field has been changed!
}
....
}
Updated: After some investigations I found that I can solve it with help of interceptors (extend EmptyInterceptor):
public class TouristInterceptor extends EmptyInterceptor{
Session session;
private Set updates = new HashSet();
public void setSession(Session session) {
this.session=session;
}
public boolean onFlushDirty(Object entity,Serializable id,
Object[] currentState,Object[] previousState,
String[] propertyNames,Type[] types)
throws CallbackException {
if (entity instanceof Tourist){
if (somethingChangedExceptLocation())
updates.add(entity);
}
return false;
}
But disadvantage of this approach is to intercept everything when you need to intercept the single entity.
Updated Questions:
How to intercept only Tourist entity flush calls?
Is that possible to do the same with help of events? Means PreUpdateEvent which contains new and old state
There is a simple non-JPA solution which is as follows but which which does have some repetitive code but is a solution when you do not have too many fields:
#Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
public void setFirstName(String firstName){
if(! this.firstName.equals(firstName){
modified = new Date();
}
this.firstName = firstName;
}
public void setLastName(String lastName){
if(! this.lastName.equals(lastName){
modified = new Date();
}
this.lastName= lastName;
}
}
Otherwise I would go with saving the previous state on load as suggested in another answer but in a slightly cleaner way.
#Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
#Transient
private Tourist previousState;
#PostLoad
public void setPreviousState() {
previousState = new Tourist();
//copy fields
}
#PreUpdate
public void preUpdate() {
if (isModified()) {
modified = new Date();
}
}
private boolean isModified() {
boolean modified = false;
if (!firstName.equals(previousState.firstName) {
modified = true;
}
//check other fields
return modified;
}
}
I really encourage you not to do this logic in your Entity !
You should decide whether to change the modified or not at your business logic.
I mean, when you are changing only the location call merge only. And whenever you are changing something else call the <Tourist_instance>.setModified(new Date()); before you call the merge.
To verify if anything else got changed, I suggest having a transient boolean field in your Entity that you set to true whenever you change something else other than location (the idea in the comment won't be sufficient to test all the fields, only if you create a transient field to remember previous value of each one of them)
You will then test this boolean in your preUpdate method
But I highly don't recommend this workaround.
Or, another highly unrecommended way :
#Entity
public class Tourist {
private long id;
private String firstName;
private String lastName;
private Date created;
private Date modified;
private String location;
#Transient
private String firstNamePrevious;
#Transient
private String lastNamePrevious;
#Transient
private Date createdPrevious;
#Transient
private Date modifiedPrevious;
#Transient
private String locationPrevious;
#PreUpdate
public void preUpdate() {
if(!onlyLocationGotChanged()){
modified = new Date();
}
}
....
#PostLoad
public void postLoad(){
//Set all previous fields to actual values
firstNamePrevious = firstName;
lastNamePrevious = lastName;
//...etc.
}
}
Although it is much late, however I enountered a problem where I required to apply update security on certain fields in entity. I solved it using Reflections. Have a look at this thread. spring security for certain entity variables

Is there any way to avoid duplicating attributes in this code?

Hi i want to know if exist a way to avoid duplicate code in this code. Now i have an action class named CustomerAction this class handle the behaviour of the request (it's like a controller) and i have a CustomerPOJO with attributes like id, name, last_name etc. Now i have to add attributes to CustomerAction to handle the data submited from the form. Is there any way to bypass the action with my CustomerPOJO ?
public class CustomerAction {
private String nombre;
private String apellido;
private String dni;
private String fechaNac;
private String obraSocial;
private String nroAsociado;
private String plan;
private String password;
private String email;
private String telParticular;
private String telCelular;
private static final Log log = LogFactory
.getLog(CustomerAction.class);
public String execute() throws Exception {
if ("cancelar".equals(this.getAccion())) {
log.debug("Executing 'cancelar' action");
return "login";
}
if ("registro".equals(accion)) {
log.debug("Executing 'registro' action");
IReferenceDataBusinessDelegate ud = new ReferenceDataBusinessDelegate();
ud.signCustomer(this.getNombre(), this.getApellido(),
this.getDni(), this.getCorreo(), this.getContrasena());
return "login";
}
}
public class Customers implements java.io.Serializable {
private long id;
private String dni;
private String name;
private String lastName;
private String email;
private String password;
private String phone;
private String cellphone;
private Date birthDate;
private Date creationDate;
private Date lastAccessDate;
private byte active;
private Set<Profesionales> profesionaleses = new HashSet<Profesionales>(0);
private Set<Pacientes> pacienteses = new HashSet<Pacientes>(0);
public Customers() {
}
}
Yes, use ModelDriven, and use a Customers as the model.
http://struts.apache.org/2.x/docs/model-driven.html
You'll need to make sure the "modelDriven" interceptor is in your stack.
How/where to initialize the model depends on your particular usage scenario; you can do it in a getter as shown in the docs, in a prepare() method if you need to reload it from the DB, etc.
I'm not sure what you mean by "bypass the action."
Please note that the ad-hoc dispatch mechanism implemented here with the accion parameter duplicates functionality provided by Struts 2 using the method attribute of the action configuration. I don't recommend using ad-hoc dispatch mechanisms as it makes understand program flow more difficult than necessary.

In Json: What exactly is a "direct self-reference"

The question may seems stupid, but for me a cycle reference is for example the object A refers an object B AND the object B refers the object A.
I am working with on a android application communicating with a GAE server with objectify DB.
My model is quite simple but I get a error:
org.codehaus.jackson.map.JsonMappingException: Direct self-reference leading to cycle (through reference chain: java.util.ArrayList[0]->com.my.model.MyMessage["senderKey"]->com.googlecode.objectify.Key["root"])
Here is my model: a MyMessage refers a MyUser (the MyUser DOESNT refer a MyMessage...
Here is the code:
public class MyMessage implements Serializable {
private static final long serialVersionUID = -1075184303389185795L;
#Id
private Long id;
#Unindexed
private String sendMessage;
#Unindexed
private String answerMessage;
private MessageStatus status = MessageStatus.FREE;
#Parent
Key<MyUser> senderKey;
Key<MyUser> answererKey;
#SuppressWarnings("unused")
private MyMessage() {
}
public MyMessage(MyUser user, String message) {
super();
this.sendMessage = message;
this.senderKey = new Key<MyUser>(MyUser.class, user.getId());
}
[... getters and setters ...]
}
.
public class MyUser implements Serializable {
private static final long serialVersionUID = 7390103290165670089L;
#Id private String id;
#SuppressWarnings("unused")
private MyUser() {
this.setId("default");
}
public MyUser(String mail) {
this.setId(mail);
}
public void setId(String mail) {
this.id = mail;
}
public String getId() {
return id;
}
}
So what is exactly a Direct self-reference ?? What is wrong with my model??
Thank you.
Key internally contains reference to parent Key, this is type-wise a reference to iteslf, i.e. a direct self-reference. This could potentially lead to endless loop, so Jackson is throwing an error.
Bottom line: Key is not serializable out-of-the-box. You might get by by writing a custom Jackson serializer/deserializer.

How to support backwards-compatible serialization when refactoring a class into an interface in Java?

Unfortunately, the situation in the question title has already happened several years in the past.
I have an Id interface which extends Serializable and contains getters for a name and id number. There is a matching IdImpl class which implements the interface. However, at some point in the past, Id was the class. There is also a serializable container object which has member fields of type Id. These container objects have been being serialized to a database for several years, so there are versions of the container object out there containing both types of Ids. When attempting to deserialize the old objects, we get an InvalidClassException. How can I deserialize the old container objects which contain the old Id concrete class instances?
Full disclosure: a couple of other changes to the Id interface have been made over the years, but I thought they looked like compatible changes (added a field to IdImpl and a getter to Id for "String idType"; generified Comparable). Could one of these changes be causing the problem too?
The classes look something like this:
// current Id interface
public interface Id extends Serializable, Comparable<Id> {
String getName();
int getIdNumber();
}
// current Id implementation
public class IdImpl implements Id {
private static final long serialVersionUID = 10329865109284L;
private String name;
private int idNumber;
IdImpl(String name, int idNumber) { this.name = name; this.idNumber = idNumber; }
#Override public String getName() { return name; }
#Override public int getIdNumber() { return idNumber; }
#Override public int compareTo(Id id) { /* some code here */ }
}
// the container object
public ContainerForm implements Serializable {
private static final long serialVersionUID = -3294779665912049275L;
private String someField;
private Id user;
private String someOtherField;
// getters and setters
}
// this is what the _old_ Id concrete class looked like
// (from source control history; not in current project)
public class Id implements Serializable, Comparable {
// never had a serialVersionUID
private String name;
private int idNumber;
Id(String name, int idNumber) { this.name = name; this.idNumber = idNumber; }
public String getName() { return name; }
public int getIdNumber() { return idNumber; }
public int compareTo(Object id) { /* some code here */ }
}
The exception we get when trying to deserialize container objects is:
java.io.InvalidClassException: mypkg.people.Id; local class incompatible: stream classdesc serialVersionUID = -6494896316839337071, local class serialVersionUID = -869017349143998644
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1583)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1496)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1732)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1947)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1753)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1329)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at mypkg.forms.FormFactory.getForm(FormFactory.java:3115)
... 34 more
As a general rule, not using serialVersionUID and turning a class into an interface is a very difficult transition to support.
In this specific instance, i believe you could support the old Id implementation by:
create a class (call it OldId) which has the old serialVersionUID and old implementation of Id (it should implement Id).
create a custom subclass of ObjectInputStream and override the readClassDescriptor() method. call the parent readClassDescriptor and
if the returned ObjectStreamClass has the Id class name and the old serialVersionUID, return the ObjectStreamClass for the new OldId class
otherwise return the given descriptor

Categories