Why doesn't Hibernate require an argument constructor?

A constructor without arguments is a requirement (tools such as using Hibernate to reflect this constructor as instance objects).

I got this wavy answer, but can anyone explain further? Thanks

+62
java orm hibernate factory-pattern
May 29 '10 at 16:43
source share
9 answers

Hibernation and code in general that creates objects through reflection uses Class<T>.newInstance() to create a new instance of your classes. This method requires that the public no-arg constructor can instantiate an object. For most cases, using the no-arg constructor is not a problem.

There are serialization-based hacks that can work without creating a no-arg constructor, since serialization uses jvm magic to create objects without calling the constructor. But this is not available for all virtual machines. For example, XStream can create instances of objects that do not have an open no-arg constructor, but only by launching it in the so-called “so-called" advanced "mode, which is available only on some virtual machines. (For more details, see Link.) Hibernate designers, Of course, we decided to maintain compatibility with all virtual machines and therefore avoid such tricks and use the officially supported reflection method Class<T>.newInstance() , which requires the no-arg constructor.

+88
Jun 04 2018-10-10T00:
source share

Sleep mode creates instances of objects. Therefore, he should be able to create them. If the no-arg constructor does not exist, Hibernate will not know how to create it, that is, which argument to pass.

The hibernate documentation says:

4.1.1. Add constructor with no arguments

All constant classes must have a default constructor (which may be non-public) so that Hibernate can instantiate using Constructor.newInstance() . It is recommended that you have a default constructor that has at least the appearance of a package for generating a proxy server while working in Hibernate.

+39
May 29 '10 at 16:47
source share

Hibernation is an ORM structure that supports a strategy for accessing fields or properties. However, it does not support constructor-based building - perhaps what would you like? - due to some problems, such as

What happens if your class contains many constructors

 public class Person { private String name; private Integer age; public Person(String name, Integer age) { ... } public Person(String name) { ... } public Person(Integer age) { ... } } 

As you can see, you are dealing with an inconsistency problem because Hibernate cannot guess which constructor should be called. For example, suppose you need to restore a saved Person object.

 Person person = (Person) session.get(Person.class, <IDENTIFIER>); 

Which constructor should call a Hibernate call to retrieve a Person object? You see?

And finally, using reflection, Hibernate can instantiate a class through its no-arg constructor. Therefore when you call

 Person person = (Person) session.get(Person.class, <IDENTIFIER>); 

Hibernate will instantiate the Person object as follows

 Person.class.newInstance(); 

Which according to API documentation

The class is created as if by a new expression with an empty argument list

Moral of history

 Person.class.newInstance(); 

looks like

 new Person(); 

Nothing more

+31
Jun 09 '10 at 3:25
source share

Erm, sorry everyone, but Hibernate does not require your classes to have a constructor without parameters. The JPA 2.0 specification requires this, and it is very weak on behalf of the JPA. Other frameworks like JAXB also require this, which is also very weak on behalf of these frameworks.

(In fact, JAXB supposedly allows founding companies, but he insists on creating these factories on their own, demanding that they have some kind of pointless designer, which in my book is just as good as not allowing the factories, like a llama!)

But Hibernate does not require such a thing.

Hibernate supports an interception mechanism (see "Interceptor" in the documentation ,) which allows you to create objects with any constructor parameters that they need.

Basically, what you do is that when you configure hibernate, you pass it an object that implements the org.hibernate.Interceptor interface, and hibernate will call the instantiate() method of that interface whenever it needs a new instance of the t object. e. Your implementation of this method can new your objects the way you like.

I did this in a project and it works like a charm. In this project, I do everything through JPA whenever possible, and I use only Hibernate features such as interceptor when I have no other choice.

Hibernate seems to be somewhat unsure of this, since at startup it gives an informational message for each of my entity classes, telling me INFO: HHH000182: No default (no-argument) constructor for class and class must be instantiated by Interceptor , but then I make an instance of them with an interceptor, and I am pleased with that.

To answer the question “why” in the question about tools other than Hibernate, the answer is “absolutely without good reason”, and this is confirmed by the presence of a sleep mode interceptor. There are many tools that could support some kind of similar mechanism for creating client objects, but they do not, therefore they create objects themselves, so they need to require constructors without parameters. I am tempted to believe that this is because the creators of these tools consider themselves programmers of ninja systems that create frameworks full of magic that will be used by uninformed application programmers who (as they think) would never have in their wildest dreams needed for such advanced designs as ... Factory Template . (Well, I have the temptation to think so. Actually, I don’t think so. I’m joking.)

+27
Apr 03 '15 at 13:34 on
source share

Actually, you can create instances of classes that do not have a 0-args constructor; you can get a list of class constructors, select one and call it with dummy parameters.

While this is possible, and I think it will work and will not be problematic, you will have to agree that it is rather strange.

Building objects the way Hibernate does (I believe that it calls the 0-arg constructor and then it probably modifies the instance fields directly through Reflection. Maybe it knows how to call setters) is slightly different from how the object should be built in Java - call the constructor with the appropriate parameters so that the new object is the object you want. I believe that creating an instance of an object and then mutating it is something like “anti-Java” (or, I would say, anti-pure theoretical Java), and, of course, if you do this using direct field manipulations, this there will be encapsulation and everything that intricately encapsulates.

I think the right way to do this would be to define in a Hibernate mapping how the object should be created from the information in the database row using the appropriate constructor ... but it would be more complex, which would mean Hibernate would be more complex, the display would be more complicated ... and everything would be more "clean"; and I don’t think it will have an advantage over the current approach (apart from feeling good about doing things “properly”).

Having said that and seeing that the Hibernate approach is not very “clean”, the obligation to have a constructor with 0-arg is not strictly necessary, but I can understand this requirement a little, although I believe that they did it in a clean “proper” way when they deviated from the “proper path” (albeit for reasonable reasons) long before that.

+6
Jun 08 '10 at 21:46
source share

Hibernate should create instances as a result of your requests (via reflection), Hibernate relies on the no-arg object constructor for this, so you need to provide a no-arg constructor. What is not clear?

+3
May 29 '10 at 16:50
source share

It is much easier to create an object using a constructor without parameters through reflection, and then fill its properties with data through reflection, than trying to compare data with arbitrary parameters of a parameterized constructor with changing name / name conflicts, an undefined logical internal constructor, a set of parameters that do not correspond to the properties of the object, etc.

Many ORMs and serializers require parameterless constructors, since parameterized constructors through reflection are very fragile, and parameterless constructors provide both application stability and developer control over object behavior.

+2
Jun 10 2018-10-10T00:
source share

Hibernate uses a proxy for lazy loading. If you do not define a constructor or make it private, some things may still work - those that are independent of the proxy mechanism. For example, loading an object (without a constructor) directly using the request API.

But if you use the session.load () method, you will encounter an InstantiationException from the proxy generator due to the lack of a constructor.

This guy reported a similar situation:

http://kristian-domagala.blogspot.com/2008/10/proxy-instantiation-problem-from.html

+1
Oct 28 '11 at 11:23
source share

Check out this section of the Java language specification, which explains the difference between static and non-stationary inner classes: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3

A static inner class is conceptually no different from a regular general class declared in a .java file.

Since Hibernate needs to instantiate ProjectPK regardless of the Project instance, ProjectPK must either be a static inner class or its own .java file is declared in it.

link org.hibernate.InstantiationException: default constructor

0
Oct 13 '14 at 2:29
source share



All Articles