Java entity - why do I need an empty constructor?
Asked Answered
Z

8

54

This might sound stupid to you, but why do I need to define an empty constructor in my @Entitys?

Every tutorial I saw said : every entity needs an empty constructor.

But Java always give you a default invisible empty constructor (if you don't redefine one).

Let me clarify.. What I understood by "need" was write.

Meaning: always write an empty constructor in your entity.

example:

@Entity
public class MyEntity implements Serializable {

   @Id
   private String str;

   public MyEntity(){}

   //here getter and setter
}

But Java always gives you this empty constructor when you don't redefine it (write an other one with parameters).

In this case writing this empty constructor seems useless.

Zoezoeller answered 7/8, 2013 at 9:4 Comment(6)
Well, it is not always necessary, unless you want to give specific values to your data members.Antagonism
@Antagonism Emtpy constructor is mandatory (yes it can be the default one, but still, there must by constructor with no arguments)Laudian
If you have a public class, java actually gives you a public visible (and not invisble) empty constructor.Hamburg
@steffen, by invisible I meant that it did not appeared on my screen in the class declaration.Zoezoeller
@Laudian I don't think that is accurate. If you don't provide the empty constructor, the compiler automatically provides a no-argument, default constructor for any class without constructors. docs.oracle.com/javase/tutorial/java/javaOO/constructors.htmlLuscious
thats the default one i have had mentioned. Besides, if it is no explicitly defined, it doesnt mean it does not exist. You have just confirmed what i have wroteLaudian
R
58

An empty constructor is needed to create a new instance via reflection by your persistence framework. If you don't provide any additional constructors with arguments for the class, you don't need to provide an empty constructor because you get one per default.

You can also use the @PersistenceConstructor annotation which looks like following

@PersistenceConstructor
public Movie(Long id) {
    this.id = id;
}

to initialise your entity if Spring Data is present in your project. Thus you can avoid the empty constructor as well.

Rainier answered 7/8, 2013 at 9:14 Comment(6)
then frameworks are bad, since they can easily use UnsafeClimate
So you are saying frameworks in general are bad because they could potentially use Unsafe? I cannot but disagree. First, for constructor injection you don't need Unsafe, reflection will do the trick. Secondly, what's the alternative, trying to write everything on your own that a big developer community has already done for you?Rainier
no I am saying that frameworks that require you to provide empty constructors are bad because they can use Unsafe instead if you do not provide empty constructorClimate
What if i needed multiple constructors? i would put @PersistenceConstructor in all of them?Evermore
no, you'd only define one primary constructor for the persistence framework. You may have additional constructors though but the persistence framework needs to know which of the available constructors should be used to initialize the entity and that's what the @PersistenceConstructor annotation is for.Rainier
Do you have any idea what could be wrong so @PersistenceConstructor annotation doesn't work? I have the same exception as in this question: #52060043. I wanted to inject DomainEventPublisher in my entity so I can publish events(something proposed here #58242589 )Mirtamirth
F
39

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.

Fool answered 7/8, 2013 at 9:8 Comment(0)
E
7

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.

Eisegesis answered 7/8, 2013 at 9:7 Comment(5)
I strongly disagree, entity has to have empty constructor for instance creation by reflection.Laudian
What JPA implementation are you familiar with? Using hibernate I am never forced to include a default constructor unless the circumstances highlighted above are present.Eisegesis
You dont have to provide constructor with no arguments, becouse you have the default one - so you DO have one. I didnt write that you have to write your own empty c right ? :)Laudian
@Laudian I think we are on the same pageEisegesis
@Laudian I don't quite understand what exactly is meant by 'reflection' here. Would you mind pointing me to a source (new to Spring, actually)?Toddy
D
5

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.

Ditzel answered 7/8, 2013 at 9:15 Comment(0)
H
3

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

Hickson answered 7/8, 2013 at 9:8 Comment(0)
F
1

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);
}
Flitch answered 29/8, 2020 at 16:18 Comment(0)
A
0

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.

Alwitt answered 7/8, 2013 at 9:13 Comment(0)
A
-1

From the JPA tag, I suppose that you are working with Java beans. Every bean needs to have the following properties:

  1. Getters and setters for all its main instance variables.

  2. An empty constructor.

  3. All its instance variables should preferably be private.

Thus the statement : "every entity needs an empty constructor".

Antagonism answered 7/8, 2013 at 9:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.