Bağımsız değişken içermeyen kurucu bir gereksinimdir (Hazırda Bekletme gibi araçlar, nesneleri başlatmak için bu yapıcıdaki yansımayı kullanır).
Bu el dalgalı cevabı aldım ama biri daha fazla açıklayabilir mi? Teşekkürler
Bağımsız değişken içermeyen kurucu bir gereksinimdir (Hazırda Bekletme gibi araçlar, nesneleri başlatmak için bu yapıcıdaki yansımayı kullanır).
Bu el dalgalı cevabı aldım ama biri daha fazla açıklayabilir mi? Teşekkürler
Caused by: org.hibernate.InstantiationException: No default constructor for entity: : hibernate.tutorial.Student
az önce karşılaştığım durumda olduğu gibi rapor verecektir
Yanıtlar:
Hazırda bekletme ve genel olarak yansıtma yoluyla nesneler oluşturan kod Class<T>.newInstance()
, sınıflarınızın yeni bir örneğini oluşturmak için kullanın . Bu yöntem, nesneyi somutlaştırabilmek için genel arginsiz bir kurucu gerektirir. Çoğu kullanım durumu için, argüman içermeyen bir kurucu sağlamak bir sorun değildir.
Serileştirme, yapıcıyı çağırmadan nesneler oluşturmak için jvm sihrini kullandığından, arginsiz bir yapıcıya sahip olmama konusunda işe yarayabilecek serileştirmeye dayalı hackler vardır. Ancak bu, tüm VM'lerde mevcut değildir. Örneğin, XStream , arginsiz bir genel yapıcıya sahip olmayan, ancak yalnızca belirli VM'lerde kullanılabilen sözde "gelişmiş" modda çalışarak nesnelerin örneklerini oluşturabilir. (Ayrıntılar için bağlantıya bakın.) Hibernate tasarımcıları kesinlikle tüm VM'lerle uyumluluğu korumayı seçti ve bu nedenle bu tür hilelerden kaçınıyor ve Class<T>.newInstance()
argümansız bir kurucu gerektiren resmi olarak desteklenen yansıtma yöntemini kullanıyor .
setAccessible(true)
.
ObjectInputStream
, sun.reflect.ReflectionFactory.getReflectionFactory().newConstructorForSerialization(classToGetInstanceOf, Object.class.getConstructor()).newInstance()
varsayılan kurucu olmayan nesnelerin örneklenmesi için satır boyunca bir şey yapar (Windows için
It can have package visibility and Hibernate should setAccessible(true)
. it
Yansıma yoluyla sınıfın somutlaştırıldığı anlamına mı geliyor? Ve ne anlama Hibernate should setAccessible(true)
geliyor?
Hazırda bekletme, nesnelerinizi somutlaştırır. Bu yüzden onları somutlaştırabilmesi gerekiyor. Eğer argümansız bir kurucu yoksa, Hibernate bunu nasıl başlatacağını , yani hangi argümanın geçeceğini bilemez .
Derin uyku belgelerine diyor ki:
4.1.1. Bağımsız değişken içermeyen bir kurucu uygulayın
Tüm kalıcı sınıfların bir varsayılan kurucuya (genel olmayan olabilir) sahip olması gerekir, böylece Hibernate bunları kullanarak başlatabilir Constructor.newInstance()
. Hazırda Bekletme'de çalışma zamanı proxy üretimi için en azından paket görünürlüğüne sahip varsayılan bir kurucunuz olması önerilir.
Erm, üzgün herkes, ama hazırda yok değil dersleriniz parametresiz yapıcı olması gerekir gerektirir. JPA 2.0 spesifikasyonu bunu gerektirir ve bu JPA adına çok saçma. JAXB gibi diğer çerçeveler de bunu gerektirir, bu da bu çerçeveler adına çok zayıftır.
(Aslında, JAXB sözde varlık fabrikalarına izin veriyor, ancak bu fabrikaları kendi başına somutlaştırmakta ısrar ediyor, onların - tahmin et ne oldu - parametresiz kurucuya sahip olmalarını gerektiriyor ki bu benim kitabımda tam olarak fabrikalara izin vermemek kadar iyidir; bu ne kadar kötü? !)
Ancak Hibernate böyle bir şeye ihtiyaç duymaz.
Hazırda bekletme, nesnelerinizi ihtiyaç duydukları kurucu parametreleriyle başlatmanıza olanak sağlayan bir durdurma mekanizmasını destekler ( belgelerdeki "Durdurucu" bölümüne bakın ).
Temel olarak, yaptığınız şey, hazırda bekletme modunu kurduğunuzda, org.hibernate.Interceptor
arabirimi uygulayan bir nesneyi iletirsiniz ve hazırda bekletme instantiate()
, sizin bir nesnenizin yeni bir örneğine ihtiyaç duyduğunda o arabirimin yöntemini çağırır, böylece bu yöntemi uygulamanız new
nesnelerinizi istediğiniz şekilde.
Bunu bir projede yaptım ve bir cazibe gibi çalışıyor. Bu projede mümkün olduğunca JPA üzerinden bir şeyler yapıyorum ve sadece başka seçeneğim olmadığında önleme gibi Hazırda Bekletme özelliklerini kullanıyorum.
Hazırda bekletme bu konuda biraz güvensiz görünüyor, çünkü başlangıç sırasında her varlık sınıfım için bir bilgi mesajı yayınlıyor, bana INFO: HHH000182: No default (no-argument) constructor for class
ve class must be instantiated by Interceptor
diyor, ancak daha sonra onları durdurucu tarafından başlatıyorum ve bundan memnunum.
Hazırda Bekletme dışındaki araçlar için sorunun "neden" bölümünü yanıtlamak için , yanıt "kesinlikle iyi bir neden yok" olur ve bu, hazırda bekletme önleyicisinin varlığıyla kanıtlanmıştır. Orada, istemci nesne somutlaştırması için bazı benzer mekanizmaları desteklemiş olabilecek birçok araç var, ama yapmıyorlar, bu yüzden nesneleri kendileri yaratıyorlar, bu yüzden parametresiz kuruculara ihtiyaç duymaları gerekiyor. Bunun gerçekleştiğine inanmak için baştan çıkarıyorum çünkü bu araçların yaratıcıları kendilerini cahil uygulama programcıları tarafından kullanılmak üzere sihirle dolu çerçeveler yaratan ninja sistem programcıları olarak görüyorlar (bu yüzden düşündükleri) en çılgın hayallerinde asla Fabrika Modeli gibi gelişmiş yapılara ihtiyaç var . (Tamam,öyle düşünmek. Ben yok aslında öyle düşünüyorum. Şaka yapıyorum.)
Caused by: org.hibernate.InstantiationException: No default constructor for entity: : hibernate.tutorial.Student
kısa süre önce javax.persistence.*;
kullanıldığı için ve yalnızca org.hibernate
Session, SessionFactory, and Configuration
Hazırda bekletme, alan veya mülk erişim stratejisini destekleyen bir ORM çerçevesidir. Ancak, yapıcı tabanlı haritalamayı desteklemiyor - belki ne istersiniz? - gibi bazı sorunlar nedeniyle
1º Sınıfınız çok sayıda kurucu içeriyorsa ne olur?
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) { ... }
public Person(String name) { ... }
public Person(Integer age) { ... }
}
Gördüğünüz gibi, bir tutarsızlık sorunuyla uğraşıyorsunuz çünkü Hibernate hangi kurucunun çağrılması gerektiğini varsayamıyor. Örneğin, depolanan bir Person nesnesini almanız gerektiğini varsayalım.
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Person nesnesini almak için hangi kurucu Hazırda Bekletme çağrısı yapmalıdır? Görebiliyor musun ?
2º Ve son olarak, yansımayı kullanarak, Hibernate argümansız kurucusu aracılığıyla bir sınıfı başlatabilir. Yani aradığında
Person person = (Person) session.get(Person.class, <IDENTIFIER>);
Hazırda bekletme, Kişi nesnenizi aşağıdaki gibi başlatacaktır
Person.class.newInstance();
API belgelerine göre hangisi
Sınıf, boş bir bağımsız değişken listesi olan yeni bir ifade ile başlatılır.
Hikayeden çıkarılacak ders
Person.class.newInstance();
benzer
new Person();
Başka hiçbir şey
name
ve age
? Değilse, daha sonra başka bir kurucu kullanıyor mu?
Aslında, 0-args yapıcısı olmayan sınıfları başlatabilirsiniz; bir sınıf kurucularının bir listesini alabilir, birini seçebilir ve sahte parametrelerle çağırabilirsiniz.
Bu mümkün olsa da, işe yarayacak ve sorunlu olmayacak olsa da, bunun oldukça tuhaf olduğunu kabul etmeniz gerekecek.
Nesneleri Hibernate'in yaptığı gibi inşa etmek (0-arg kurucusunu çağırdığına inanıyorum ve sonra muhtemelen örneğin alanlarını doğrudan Yansıma yoluyla değiştiriyor. Belki de ayarlayıcıları nasıl çağıracağını biliyor) bir nesnenin nasıl inşa edilmesi gerektiğine biraz ters gidiyor Yeni nesnenin istediğiniz nesne olması için oluşturucuyu uygun parametrelerle Java ile çağırın. Bir nesneyi örneklemenin ve sonra onu mutasyona uğratmanın bir şekilde "Java karşıtı" olduğuna inanıyorum (veya diyebilirim ki, anti-saf teorik Java) - ve kesinlikle, bunu doğrudan alan manipülasyonu yoluyla yaparsanız, kapsülleme ve tüm bu süslü kapsülleme şeylerine gider .
Bunu yapmanın uygun yolunun, Hazırda Bekletme eşlemesinde bir nesnenin doğru kurucu kullanılarak veritabanı satırındaki bilgilerden nasıl başlatılacağını tanımlamak olacağını düşünüyorum ... ancak bu daha karmaşık olacaktır - yani her iki Hazırda Bekletme eşit olacaktır. daha karmaşık, haritalama daha karmaşık olacaktır ... ve hepsi daha "saf" olacaktır; ve bunun mevcut yaklaşıma göre bir avantajı olacağını düşünmüyorum (işleri "doğru şekilde" yapma konusunda iyi hissetmek dışında).
Bunu söyledikten sonra ve Hibernate yaklaşımının çok "temiz" olmadığını görünce, 0-arg oluşturucuya sahip olma yükümlülüğü kesinlikle gerekli değildir, ancak bunu tamamen "doğru bir şekilde yaptıklarına inanıyorum, ancak gereksinimi biraz anlayabiliyorum "uygun yoldan" (makul nedenlerle de olsa) çok daha önce saptıkları zaman.
Hibernate'in sorgularınızın sonucu olarak (yansıtma yoluyla) örnekler oluşturması gerekir, Hibernate bunun için varlıkların argüman içermeyen yapıcısına güvenir, bu nedenle argüman içermeyen bir kurucu sağlamanız gerekir. Açık olmayan ne?
private
kurucu hangi koşullar altında yanlıştır? JPA varlığım için java.lang.InstantiationException
bir private
kurucu ile bile görüyorum . referans .
Yansıtma yoluyla parametresiz bir kurucu ile nesne oluşturmak ve daha sonra özelliklerini yansıtma yoluyla verilerle doldurmak, verileri parametreli bir kurucunun keyfi parametreleriyle, değişen adlar / adlandırma çakışmaları, yapıcı içindeki tanımsız mantıkla denemek ve eşleştirmekten çok daha kolaydır. parametre kümeleri bir nesnenin özellikleriyle eşleşmiyor, vb.
Birçok ORM ve serileştirici parametresiz oluşturucular gerektirir, çünkü yansıtma yoluyla paramterize oluşturucular çok kırılgandır ve parametresiz oluşturucular hem uygulamaya kararlılık hem de geliştiriciye nesne davranışı üzerinde kontrol sağlar.
Hibernate, geç yükleme için proxy'ler kullanır. Bir kurucu tanımlamazsanız veya onu özel yapmazsanız, proxy mekanizmasına bağlı olmayan birkaç şey hala işe yarayabilir. Örneğin, nesneyi (yapıcı olmadan) doğrudan sorgu API'si kullanarak yükleme.
Ancak, session.load yöntemini () kullanırsanız, yapıcının kullanılabilir olmaması nedeniyle proxy oluşturucu lib'den InstantiationException ile karşılaşırsınız.
Bu adam benzer bir durum bildirdi:
http://kristian-domagala.blogspot.com/2008/10/proxy-instantiation-problem-from.html
Statik ve statik olmayan iç sınıflar arasındaki farkı açıklayan Java dil spesifikasyonunun bu bölümüne bakın: http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3
Statik bir iç sınıf, kavramsal olarak bir .java dosyasında bildirilen normal bir genel sınıftan farklı değildir.
Hibernate'in Project örneğinden bağımsız olarak ProjectPK'yi başlatması gerektiğinden, ProjectPK'nin statik bir iç sınıf olması veya kendi .java dosyasında bildirilmesi gerekir.
başvuru org.hibernate.InstantiationException: Varsayılan yapıcı yok
Hibernate, genellikle çağırdığınızda get()
veya load()
yöntemleri kullandığınızda, Entity fasulye örneğini oluşturmak için Reflection API kullanır . Yöntem Class.newInstance()
bunun için kullanılır ve no-args
kurucu gerektirir . Bu nedenle, varlık fasulye'lerinde args kurucunuz yoksa, hazırda bekletme bunu başlatamaz ve HibernateException alırsınız.
The no-argument constructor is a requirement
Yanlış olan iddia ve bunun gerçekten böyle olup olmadığını sorgulamadan bunun neden böyle olduğunu açıklamaya devam eden tüm yanıtlar (ödül almış olan kabul edilen yanıt dahil) yanlıştır . Bu yanıtı görün: stackoverflow.com/a/29433238/773113