This might sound stupid to you,
but why do I need to define an empty constructor in my @Entity
s?
Every tutorial I saw said : every entity needs an empty
Java not always give you a default invisible empty constructor if your class got argument constructor, you have to define the empty constructor by your own.
As you specified the "JPA" tag, I assume your question applies to JPA only and not empty constructors in general.
Persitence frameworks often use reflection and more specifically Class<T>.newInstance()
to instantiate your objects, then call getters/setters by introspection to set the fields.
That is why you need an empty constructor and getters/setters.
See this StackOverflow question about empty constructors in Hibernate.
All the answers are fine.
But let's talk with code. Following snippets of code will give you more clarity.
PersonWithImplicitConstructor.java
public class PersonWithImplicitConstructor {
private int id;
private String name;
}
First we have to compile the .java
file
javac PersonWithImplicitConstructor.java
Then class file will be generated.
Running the javap
on top this class file will give you the following information.
javap PersonWithImplicitConstructor.class
Compiled from "PersonWithImplicitConstructor.java"
public class PersonWithImplicitConstructor {
public PersonWithImplicitConstructor();
}
NOTE: If you want more information, you can use -p
flag on javap
.
The next java file will have parameterised constructor only.
PersonWithExplicitConstructor.java
public class PersonWithExplicitConstructor {
private int id;
private String name;
public PersonWithExplicitConstructor(int id, String name) {
this.id = id;
this.name = name;
}
}
javac PersonWithExplicitConstructor.java
javap PersonWithExplicitConstructor.class
Compiled from "PersonWithExplicitConstructor.java"
public class PersonWithExplicitConstructor {
public PersonWithExplicitConstructor(int, java.lang.String);
}
PersonWithBothConstructors.java
public class PersonWithBothConstructors {
private int id;
private String name;
public PersonWithBothConstructors() {
}
public PersonWithBothConstructors(int id, String name) {
this.id = id;
this.name = name;
}
}
javac PersonWithBothConstructors.java
javap PersonWithBothConstructors.class
Compiled from "PersonWithBothConstructors.java"
public class PersonWithBothConstructors {
public PersonWithBothConstructors();
public PersonWithBothConstructors(int, java.lang.String);
}
Explicitly defining a default constructor is not necessary unless you provide another constructor for the entity. If you provide another constructor, aside from one with the default constructor's signature, the default constructor will not be created.
Since JPA implementations rely upon the existence of a default constructor it is then necessary to include the default constructor that will be omitted.
But java always give you a default invisible empty constructor (if you don't redefine one).
This statement is true only when you don't provide any constructor in your class. If an argument constructor is provided in your class, then jvm will not add the no-argument constructor.
Actually you don't need to write it. You have it by default. Sometimes you can create private
constructor to prevent users to use default
public class MyClass{
private MyClass(){}
}
For singelton patterns, for example you can block using default constructor.
Sometimes, when you use Gson
plugin to convert String Json data to Object, it demands to write default constructor, otherwise it doesn't work